Thursday, January 4, 2018

Tappable links in UITextView

UITextView’s Data Detectors are helpful in detecting the urls/phone numbers in the content we display in it. 



However, links in UITextView don’t work on press, only when long pressing them works.

The work around for this is to add a Tap Gesture as shown below.


Swift




  let tapRecognizer = UITapGestureRecognizer(target: self, 
                         action: #selector(self.tappedTextView))

  sampleNotes.addGestureRecognizer(tapRecognizer)

    @objc func tappedTextView(tapGesture: 
                                    UIGestureRecognizer) {

        let textView = tapGesture.view as! UITextView
        let tapLocation = tapGesture.location(in: textView)
        let textPosition = textView.closestPosition(to: 
                                                                   tapLocation)
        let attr: NSDictionary = textView.textStyling(at: 
                      textPosition!, in: .forward)! as NSDictionary

        if let url: NSURL = attr[NSAttributedStringKey.link] as? 
                                                                        NSURL 
         {
            tappedOn(url: url as URL)
        }
    }
    
    func tappedOn(url: URL) {
        print(url)
    }



Objective C




   
  UITapGestureRecognizer *tapGesture = 
           [[UITapGestureRecognizer alloc] initWithTarget:cell 
                     action:@selector(tappedTextView:)];

    [sampleNotes addGestureRecognizer:tapGesture];

- (void)tappedTextView:
                    (UITapGestureRecognizer*)tapGesture {

    if (tapGesture.state != UIGestureRecognizerStateEnded) {
        return;
    }

    UITextView *textView = (UITextView *)tapGesture.view;

    CGPoint tapLocation = [tapGesture 
                                         locationInView:textView];

    UITextPosition *textPosition = [textView 
                              closestPositionToPoint:tapLocation];

    NSDictionary *attributes = [textView 
                                  textStylingAtPosition:textPosition 
                  inDirection:UITextStorageDirectionForward];

    NSURL *url = attributes[NSLinkAttributeName];

    if (url) {
        [self tappedOnLink:url];
    }
}



Here, We are getting the tap location and checking whether the tapped area is of a link.


Hope this post is useful. Feel Free to comment incase of any queries.