UITextView中的超链接

时间:2014-11-16 21:59:15

标签: ios objective-c ios8 uitextview

我正在尝试使用UITextView创建hyperlink,以便当用户点击该链接时,系统会将其转到safari以打开该网页。我已阅读textview的链接检测器,但如果文本中存在实际网址(即www.google.com),那些样本始终显示链接检测有效。我希望它是常规文本,在单击时打开关联的URL。 (即Google是文本,点击后会打开一个网址www.google.com)。如何在iOS7 / 8中完成此操作?

6 个答案:

答案 0 :(得分:18)

使用NSAttributedString

NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:@"Google" 
                                                                       attributes:@{ NSLinkAttributeName: [NSURL URLWithString:@"http://www.google.com"] }];
self.textView.attributedText = attributedString;

当然,您可以只将文本的一部分设置为链接。请详细了解NSAttributedString here

如果您希望在打开链接之前获得更多控制权并执行某些操作。您可以将代理设置为UITextView

- (void)viewDidLoad {
    ...
    self.textView.delegate = self; // self must conform to UITextViewDelegate protocol
}

...

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
    // Do whatever you want here
    NSLog(@"%@", URL); // URL is an instance of NSURL of the tapped link
    return YES; // Return NO if you don't want iOS to open the link
}

答案 1 :(得分:10)

Swift 3,iOS10,Xcode 9

@ sikhapol的答案真的很好,如果你确切地知道你要解析的单词,如“单词字典”一些如何

所有关于它自己显示的字符串 在UITextView中

我的解决方案基于文字渲染 如果你让UITextView渲染一个html标签,你可以使用href标签

以下是您可以使用的一些代码参考

首先,您需要从界面构建器或表单代码配置UITextView 到

  1. 可选
  2. 数据检测
  3. 注意:不要使textview可编辑

    界面构建器

    enter image description here

    <强>编程

             let htmlData = NSString(string: "go to <a href=\"http://www.google.com\">google</a> and search for it").data(using: String.Encoding.unicode.rawValue)
    
    
            let attributedString = try! NSAttributedString(data: htmlData!, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
            yourUIViewView.isSelectable = true
            yourUIViewView.dataDetectorTypes = .link
            yourUIViewView.attributedText = attributedString
            yourUIViewView.delegate = self
    

    用于UITextViewDelegate

        func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
    
           // check for the url string for performing your own custom actions here
          let urlString = URL.absoluteString
    
           // Return NO if you don't want iOS to open the link
            return true
         }
    

答案 2 :(得分:4)

我编写和使用的一个漂亮的小扩展(Swift 4.2,在iOS 12.1上测试)

extension NSAttributedString {
    func replace(placeholder: String, with hyperlink: String, url: String) -> NSAttributedString {
        let mutableAttr = NSMutableAttributedString(attributedString: self)

        let hyperlinkAttr = NSAttributedString(string: hyperlink, attributes: [NSAttributedString.Key.link: URL(string: url)!])

        let placeholderRange = (self.string as NSString).range(of: placeholder)

        mutableAttr.replaceCharacters(in: placeholderRange, with: hyperlinkAttr)
        return mutableAttr
    }
}

用法:

//Set through code or through interface builder
footerText.isSelectable = true
footerText.dataDetectorTypes = .link

//Keeps the original formatting from xib or storyboard
footerText.text = "By continuing, you are indicating that you accept our @Terms@ and @Privacy@."
footerText.attributedText = footerText.attributedText?
        .replace(placeholder: "@Terms@", with: "Terms and Conditions", url: AppUrl.terms)
        .replace(placeholder: "@Privacy@", with: "Privacy Policy", url: AppUrl.privacy)

答案 3 :(得分:1)

此代码示例在同一标签中有两个不同的链接,并且URL颜色设置为避免默认的蓝色。

UITextView * textTerm = [UITextView new];
NSMutableAttributedString *attrRight = [[NSMutableAttributedString alloc] initWithString:@"Terms of Service"
                                                                       attributes:@{ NSLinkAttributeName: [NSURL URLWithString:@"http://www.google.com"] }];
NSMutableAttributedString *attrLeft = [[NSMutableAttributedString alloc] initWithString:@"Privacy Policy"
                                                                       attributes:@{ NSLinkAttributeName: [NSURL URLWithString:@"http://www.google.com"] }];
[attrRight appendAttributedString:attrLeft];
textTerm.attributedText = attrRight;
textTerm.editable = NO;
textTerm.dataDetectorTypes = UIDataDetectorTypeAll;
textTerm.linkTextAttributes = [UIColor whiteColor];
textTerm.backgroundColor = [UIColor clearColor];

答案 4 :(得分:0)

如果您想在UITextView中使用活动子字符串,那么您可以使用我的扩展TextView ...简短而简单。您可以根据需要进行编辑。

如何使用(range = substring location):

[self.textView addTapActionWithRange:range withActionBlock:^{
      // anything you want to do - show something
}];

结果: enter image description here

源代码:https://github.com/marekmand/ActiveSubstringTextView

答案 5 :(得分:0)

由于编辑队列已满,我将在此处发布我的答案版本。它基于 Amr Angry 的回答。

我正在使用 DispatchQueue.main.async { ... } 因为如果 NSAttributedString 在后台线程上运行,应用程序将会崩溃。

guard let htmlData = NSString(string: "go to <a href=\"http://www.google.com\">google</a> and search for it").data(using: String.Encoding.unicode.rawValue) else { return }
    
DispatchQueue.main.async {
    do {

    let attributedString = try NSAttributedString(data: htmlData, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
    yourUIViewView.isSelectable = true
    yourUIViewView.dataDetectorTypes = .link
    yourUIViewView.attributedText = attributedString
    yourUIViewView.delegate = self

    } catch {
        print("Cannot setup link with \(htmlData)!")
    }
}

func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {

    // Return NO if you don't want iOS to open the link
    return true
}