首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在UILabel的NSAttributedString中创建可点击的“链接”?

在UILabel的NSAttributedString中创建可点击的“链接”?
EN

Stack Overflow用户
提问于 2009-08-10 19:56:16
回答 22查看 263.2K关注 0票数 273

我已经找了好几个小时了,但是我失败了。我可能甚至不知道我应该寻找什么。

许多应用程序都有文本,在此文本中是圆角矩形中的web超链接。当我单击它们时,UIWebView将打开。令我困惑的是,他们经常有自定义链接,例如,如果单词以#开头,它也是可点击的,应用程序会打开另一个视图进行响应。我该怎么做呢?是否可以使用UILabel,或者我是否需要UITextView或其他什么?

EN

回答 22

Stack Overflow用户

发布于 2015-12-01 15:14:53

这是一个老问题,但是如果任何人都可以使用UITextView而不是UILabel,那么就很容易了。标准的网址,电话号码等将被自动检测(并可点击)。

但是,如果您需要自定义检测,也就是说,如果您希望在用户单击特定单词后能够调用任何自定义方法,则需要使用具有指向自定义URL方案的NSLinkAttributeName属性的NSAttributedStrings (而不是默认使用http url方案)。Ray Wenderlich has it covered here

引用上述链接中的代码:

代码语言:javascript
复制
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"This is an example by @marcelofabri_"];
[attributedString addAttribute:NSLinkAttributeName
                     value:@"username://marcelofabri_"
                     range:[[attributedString string] rangeOfString:@"@marcelofabri_"]];

NSDictionary *linkAttributes = @{NSForegroundColorAttributeName: [UIColor greenColor],
                             NSUnderlineColorAttributeName: [UIColor lightGrayColor],
                             NSUnderlineStyleAttributeName: @(NSUnderlinePatternSolid)};

// assume that textView is a UITextView previously created (either by code or Interface Builder)
textView.linkTextAttributes = linkAttributes; // customizes the appearance of links
textView.attributedText = attributedString;
textView.delegate = self;

要检测这些链接点击,请实现以下代码:

代码语言:javascript
复制
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
    if ([[URL scheme] isEqualToString:@"username"]) {
        NSString *username = [URL host]; 
        // do something with this username
        // ...
        return NO;
    }
    return YES; // let the system open this URL
}

PS:确保你的UITextViewselectable

票数 63
EN

Stack Overflow用户

发布于 2010-03-30 23:58:03

如果您没有为UIButtonTypeCustom设置任何图像,那么它就是一个可点击的标签。

票数 34
EN

Stack Overflow用户

发布于 2017-11-07 00:00:06

将@samwize的扩展转换为Swift 4:

代码语言:javascript
复制
extension UITapGestureRecognizer {
    func didTapAttributedTextInLabel(label: UILabel, inRange targetRange: NSRange) -> Bool {
        guard let attrString = label.attributedText else {
            return false
        }

        let layoutManager = NSLayoutManager()
        let textContainer = NSTextContainer(size: .zero)
        let textStorage = NSTextStorage(attributedString: attrString)

        layoutManager.addTextContainer(textContainer)
        textStorage.addLayoutManager(layoutManager)

        textContainer.lineFragmentPadding = 0
        textContainer.lineBreakMode = label.lineBreakMode
        textContainer.maximumNumberOfLines = label.numberOfLines
        let labelSize = label.bounds.size
        textContainer.size = labelSize

        let locationOfTouchInLabel = self.location(in: label)
        let textBoundingBox = layoutManager.usedRect(for: textContainer)
        let textContainerOffset = CGPoint(x: (labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x, y: (labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y)
        let locationOfTouchInTextContainer = CGPoint(x: locationOfTouchInLabel.x - textContainerOffset.x, y: locationOfTouchInLabel.y - textContainerOffset.y)
        let indexOfCharacter = layoutManager.characterIndex(for: locationOfTouchInTextContainer, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
        return NSLocationInRange(indexOfCharacter, targetRange)
    }
}

设置识别器(为文本和内容着色后):

代码语言:javascript
复制
lblTermsOfUse.isUserInteractionEnabled = true
lblTermsOfUse.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTapOnLabel(_:))))

...then手势识别器:

代码语言:javascript
复制
@objc func handleTapOnLabel(_ recognizer: UITapGestureRecognizer) {
    guard let text = lblAgreeToTerms.attributedText?.string else {
        return
    }

    if let range = text.range(of: NSLocalizedString("_onboarding_terms", comment: "terms")),
        recognizer.didTapAttributedTextInLabel(label: lblAgreeToTerms, inRange: NSRange(range, in: text)) {
        goToTermsAndConditions()
    } else if let range = text.range(of: NSLocalizedString("_onboarding_privacy", comment: "privacy")),
        recognizer.didTapAttributedTextInLabel(label: lblAgreeToTerms, inRange: NSRange(range, in: text)) {
        goToPrivacyPolicy()
    }
}
票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1256887

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档