Home > Back-end >  How to open a view controller on click of hyperlink on UILabel in Objective-C
How to open a view controller on click of hyperlink on UILabel in Objective-C

Time:04-09

I have to open a view controller via a hyperlink on a UILabel. This only worked halfway for me. I cannot use UITextView according to my project requirement.

The following code creates a hyperlink on a UILabel and detects touch on the link but I want to open a view controller instead of an URL.

@property (weak, nonatomic) @IBOutlet UILabel *label;
NSLayoutManager *layoutManager;
NSTextContainer *textContainer;
NSTextStorage *textStorage;

Create hyperlink on a UILabel:

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"String with a link" attributes:nil];
NSRange linkRange = NSMakeRange(14, 4);
NSDictionary *linkAttributes = @{ NSForegroundColorAttributeName : [UIColor colorWithRed:0.05 green:0.4 blue:0.65 alpha:1.0],
                                  NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle) };
[attributedString setAttributes:linkAttributes range:linkRange];
_label.attributedText = attributedString;

// To detect touches on this Hyperlink.

_label.userInteractionEnabled = YES;
[_label addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapOnLabel:)]];

To Find out tap was on link, not on any other portion of the label.

// Create instances of NSLayoutManager, NSTextContainer and NSTextStorage

layoutManager = [[NSLayoutManager alloc] init];
textContainer = [[NSTextContainer alloc] initWithSize:CGSizeZero];
textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString];

// Configure layoutManager, textStorage and textContainer

[layoutManager addTextContainer:textContainer];

[textStorage addLayoutManager:layoutManager];

textContainer.lineFragmentPadding = 0.0;
textContainer.lineBreakMode = _label.lineBreakMode;
textContainer.maximumNumberOfLines =_label.numberOfLines;

// each time the label changes its frame, update textContainer's size:

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    textContainer.size = self.label.bounds.size;
}

// detect whether the tap was exactly on the link:

- (void)handleTapOnLabel:(UITapGestureRecognizer *)tapGesture
{
    CGPoint locationOfTouchInLabel = [tapGesture locationInView:tapGesture.view];
    CGSize labelSize = tapGesture.view.bounds.size;
    CGRect textBoundingBox = [layoutManager usedRectForTextContainer:textContainer];
    CGPoint textContainerOffset = CGPointMake((labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x,
                                              (labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y);
    CGPoint locationOfTouchInTextContainer = CGPointMake(locationOfTouchInLabel.x - textContainerOffset.x,
                                                         locationOfTouchInLabel.y - textContainerOffset.y);
    NSInteger indexOfCharacter = [layoutManager characterIndexForPoint:locationOfTouchInTextContainer
                                                       inTextContainer:textContainer
                              fractionOfDistanceBetweenInsertionPoints:nil];
    NSRange linkRange = NSMakeRange(14, 4);
    if (NSLocationInRange(indexOfCharacter, linkRange)) {
        // Open an URL, or handle the tap on the link in any other way
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://stackoverflow.com/"]];
    }
}

// using this function to present newViewController

-(void)navigateToTATViewController{
    TATViewController *tatVC = [[self getStoryboardWithStoryboardType: kListingStoryboard] instantiateViewControllerWithIdentifier: @"TATViewControllerID"];
    [self.navigationController presentViewController: tatVC animated:true completion:nil];
}

CodePudding user response:

So basically you need to update the line:

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://stackoverflow.com/"]];

and replace it with [self navigateToTATViewController];

  • Related