10

I have used "Register yourself" as text. I want to make it as link. And by clicking on that link, it should open Register.xib.

How can I get this link??

Jon Egerton
  • 40,401
  • 11
  • 97
  • 129
Krunal
  • 1,318
  • 1
  • 13
  • 31

6 Answers6

12

Kareem is right. Create a UIButton object, set it's type to "Custom" and then you can give it a title. Connect the action to a method which pushes or presents your Register view controller and you will be all set.

You'll probably want to give some indication to the user that the text is a clickable link. Either set the color of the text to blue. Another, completely separate option, is to use a NSAttributedString (which has an underline attribute) to indicate to the user that the text is clickable. That requires an Open Source replacement for UITextView (which you can learn more about from this related question).

Community
  • 1
  • 1
Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
2

I think by below you will get what you want...

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{   
    NSSet *allTouches = [event allTouches];
    if ([allTouches count] == 1)
    {
        UITouch *touch = (UITouch *)[allTouches anyObject];
        CGPoint touchPoint = [touch locationInView:self];

        // Convert to coordinate system of current view
        touchPoint.y -= self.bounds.size.height;
        touchPoint.y *= -1;

        CGPathRef statusPath = CTFrameGetPath(statusCTFrame);
        NSString *touchedInterStr = nil;
        if (CGPathContainsPoint(statusPath, NULL, touchPoint, FALSE))
        {
            touchedInterStr = [self getInteractiveStringInFrame:statusCTFrameatPosition:touchPoint];
        }
        else
        {
            return ;
        }
    }
}
Spontifixus
  • 6,570
  • 9
  • 45
  • 63
iTrained
  • 31
  • 3
2

There's a middle ground that's worth mentioning. Using UIButton with UIButtonTypeCustom has some shortcomings, namely that you have limited control over the text styling (e.g. you cannot make it right or left aligned, it will always be centered).

Using NSAttributedString can be overkill, and tough to implement if you're unfamiliar with NSAttributedString, CoreText etc.

A solution I've used is a simple subclass of UIControl which allows more customization than subclassing UIButton and less hassle than NSAttributedString et al. The UIControl approach is only appropriate if the entire string will be a "link".

You would do something like this in your UIControl subclass:

  • Add a UILabel subview in the init method
  • Configure the UILabel with your desired backgroundColor, textColor, textAlignment etc, including changes to the UILabel layer if you want the background to appear like Twitter's in-tweet links in their iOS App
  • Override the setHighlighted: method to customize the look and feel changes on touch/tracking
  • Add @property setters in the .h file so the owning class can set the state
Alfie Hanssen
  • 16,964
  • 12
  • 68
  • 74
0

Take a button and set title of the button which you want to set as hyperlink Text. You can choose default and custom button type button in iOS 7 and iOS 8, but for below iOS 7 you have to take button type custom only. You can change colour of the text to highlight text for UI and than add whatever action you want to add on that button click. It will work like charm, good luck.

Tejinder
  • 1,507
  • 19
  • 22
0

Take a look to TTTAttributedLabel. Is really simple to configure links, phones, etc.

halbano
  • 1,135
  • 14
  • 34
0

First, construct the attributed string and save the range of the interactive text and the text itself.

Then, draw the attributed string with CoreText Framework, keep the CTFrameRef.

CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, bounds);

CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
CFRelease(framesetter);

CTFrameDraw(frame, context);
//CFRelease(frame);

CGPathRelease(path);

The last, override the [view touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event] like this:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{   
    NSSet *allTouches = [event allTouches];
    if ([allTouches count] == 1) {
       UITouch *touch = (UITouch *)[allTouches anyObject];
       CGPoint touchPoint = [touch locationInView:self];

       // Convert to coordinate system of current view
       touchPoint.y -= self.bounds.size.height;
       touchPoint.y *= -1;

       CGPathRef statusPath = CTFrameGetPath(statusCTFrame);
       NSString *touchedInterStr = nil;
       if (CGPathContainsPoint(statusPath, NULL, touchPoint, FALSE)) {
          touchedInterStr = [self getInteractiveStringInFrame:statusCTFrame atPosition:touchPoint];
       } else {
          return ;
       }
   }
}

- (NSString *)getInteractiveStringInFrame:(CTFrameRef)frame atPosition:(CGPoint)point
{
    CGPathRef path = CTFrameGetPath(frame);
    CGRect rect;
    CGPathIsRect(path, &rect);

    // Convert point into rect of current frame, to accurately perform hit testing on CTLine
    CGPoint pointInsideRect = point;
    pointInsideRect.x = point.x - rect.origin.x;

    CFArrayRef lines = CTFrameGetLines(statusCTFrame);
    CFIndex count = CFArrayGetCount(lines);
    CGFloat curUpBound = rect.origin.y + rect.size.height;
    CFIndex touchedIndex = -1;
    for (CFIndex pos = 0; pos < count; pos++) {
        CTLineRef curLine = CFArrayGetValueAtIndex(lines, pos);
        CGFloat ascent, descent, leading;
        CTLineGetTypographicBounds(curLine, &ascent, &descent, &leading);
        CGFloat curHeight = ascent + descent + leading;
        if (pointInsideRect.y >= curUpBound-curHeight && pointInsideRect.y <= curUpBound){
            touchedIndex = CTLineGetStringIndexForPosition(curLine, pointInsideRect);   // Hit testing
            break;
        }
        curUpBound -= curHeight;
    }
    if (touchedIndex == -1)
        return nil;

    NSEnumerator *enumerator = [interactiveStrs objectEnumerator];
    InteractiveString *curString;
    while ((curString = (InteractiveString *)[enumerator nextObject])) {
        if (NSLocationInRange(touchedIndex, curString.range)) {
            return curString.content;
        }
    }

    return nil;
}

You get the interactive text in touchesEnded, then you could do anything you want, like trigger a delegate method.

PS: this is the old-fashion solution, I heard that iOS5 had provided something like an enhanced UIWebView to implement the requirements, maybe you could check the apple sdk document library.

huubby
  • 370
  • 2
  • 10