Create tap-able “links” in the NSAttributedString of a UILabel?

前端 未结 30 2614
半阙折子戏
半阙折子戏 2020-11-22 02:07

I have been searching this for hours but I\'ve failed. I probably don\'t even know what I should be looking for.

Many applications have text and in this text are web

30条回答
  •  渐次进展
    2020-11-22 02:44

    Drop-in solution as a category on UILabel (this assumes your UILabel uses an attributed string with some NSLinkAttributeName attributes in it):

    @implementation UILabel (Support)
    
    - (BOOL)openTappedLinkAtLocation:(CGPoint)location {
      CGSize labelSize = self.bounds.size;
    
      NSTextContainer* textContainer = [[NSTextContainer alloc] initWithSize:CGSizeZero];
      textContainer.lineFragmentPadding = 0.0;
      textContainer.lineBreakMode = self.lineBreakMode;
      textContainer.maximumNumberOfLines = self.numberOfLines;
      textContainer.size = labelSize;
    
      NSLayoutManager* layoutManager = [[NSLayoutManager alloc] init];
      [layoutManager addTextContainer:textContainer];
    
      NSTextStorage* textStorage = [[NSTextStorage alloc] initWithAttributedString:self.attributedText];
      [textStorage addAttribute:NSFontAttributeName value:self.font range:NSMakeRange(0, textStorage.length)];
      [textStorage addLayoutManager:layoutManager];
    
      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(location.x - textContainerOffset.x, location.y - textContainerOffset.y);
      NSInteger indexOfCharacter = [layoutManager characterIndexForPoint:locationOfTouchInTextContainer inTextContainer:textContainer fractionOfDistanceBetweenInsertionPoints:nullptr];
      if (indexOfCharacter >= 0) {
        NSURL* url = [textStorage attribute:NSLinkAttributeName atIndex:indexOfCharacter effectiveRange:nullptr];
        if (url) {
          [[UIApplication sharedApplication] openURL:url];
          return YES;
        }
      }
      return NO;
    }
    
    @end
    

提交回复
热议问题