ios 如何在 UITextView 中显示可点击的链接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34425096/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:27:29  来源:igfitidea点击:

How to display clickable links in UITextView

iosswiftuitextview

提问by jhk727

I am trying to display an attributed string in a UITextview with clickable links. I've created a simple test project to see where I'm going wrong and still can't figure it out. I've tried enabling user interaction and setting the shouldInteractWithURLs delegate method, but it's still not working. Here's my code (for a view controller that only contains a textview)

我试图在带有可点击链接的 UITextview 中显示属性字符串。我创建了一个简单的测试项目来查看我哪里出错了,但仍然无法弄清楚。我已经尝试启用用户交互并设置 shouldInteractWithURLs 委托方法,但它仍然无法正常工作。这是我的代码(对于仅包含 textview 的视图控制器)

  @IBOutlet weak var textView: UITextView!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    let string = "Google"
    let linkString = NSMutableAttributedString(string: string)
    linkString.addAttribute(NSLinkAttributeName, value: NSURL(string: "https://www.google.com")!, range: NSMakeRange(0, string.characters.count))
    linkString.addAttribute(NSFontAttributeName, value: UIFont(name: "HelveticaNeue", size: 25.0)!, range: NSMakeRange(0, string.characters.count))
    textView.attributedText = linkString
    textView.delegate = self
    textView.selectable = true
    textView.userInteractionEnabled = true
}

And here are the delegate methods I've implemented:

这是我实现的委托方法:

func textViewShouldBeginEditing(textView: UITextView) -> Bool {
    return false
}

func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool {
    return true
}

This still isn't working. I've searched on this topic and nothing has helped yet. Thanks so much in advance.

这仍然不起作用。我已经搜索过这个主题,但没有任何帮助。非常感谢。

回答by Rashwan L

Just select the UITextViewin your storyboard and go to "Show Attributes inspector" and select selectableand links. As the image below shows. Make sure Editableis unchecked.

只需UITextView在故事板中选择 ,然后转到“显示属性检查器”并选择selectablelinks。如下图所示。确保Editable未选中。

enter image description here

在此处输入图片说明

回答by Maulik Patel

For swift3.0

对于 swift3.0

  override func viewDidLoad() {
     super.viewDidLoad()

  let linkAttributes = [
        NSLinkAttributeName: NSURL(string: "http://stalwartitsolution.co.in/luminutri_flow/terms-condition")!
        ] as [String : Any]
  let attributedString = NSMutableAttributedString(string: "Please tick box to confirm you agree to our Terms & Conditions, Privacy Policy, Disclaimer. ")

  attributedString.setAttributes(linkAttributes, range: NSMakeRange(44, 18))

  attributedString.addAttribute(NSUnderlineStyleAttributeName, value: NSNumber(value: 1), range: NSMakeRange(44, 18))

  textview.delegate = self
  textview.attributedText = attributedString
  textview.linkTextAttributes = [NSForegroundColorAttributeName: UIColor.red]
  textview.textColor = UIColor.white
  }


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

回答by Jad

Swift 3 iOS 10:Here's Clickable extended UITextView that detect websites inside the textview automatically as long as the link start with www.for example: www.exmaple.comif it exist anywhere in the text will be clickable. Here's the class:

Swift 3 iOS 10:这是可点击的扩展 UITextView,只要链接以www开头,它就会自动检测文本视图中的网站例如:www.exmaple.com如果它存在于文本中的任何位置,则可点击。这是课程:

import Foundation
import UIKit




public class ClickableTextView:UITextView{



    var tap:UITapGestureRecognizer!
    override public init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        print("init")
        setup()
    }
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }


    func setup(){

        // Add tap gesture recognizer to Text View
        tap = UITapGestureRecognizer(target: self, action: #selector(self.myMethodToHandleTap(sender:)))
        //        tap.delegate = self
        self.addGestureRecognizer(tap)
    }

    func myMethodToHandleTap(sender: UITapGestureRecognizer){

        let myTextView = sender.view as! UITextView
        let layoutManager = myTextView.layoutManager

        // location of tap in myTextView coordinates and taking the inset into account
        var location = sender.location(in: myTextView)
        location.x -= myTextView.textContainerInset.left;
        location.y -= myTextView.textContainerInset.top;


        // character index at tap location
        let characterIndex = layoutManager.characterIndex(for: location, in: myTextView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

        // if index is valid then do something.
        if characterIndex < myTextView.textStorage.length {

            let orgString = myTextView.attributedText.string


            //Find the WWW
            var didFind = false
            var count:Int = characterIndex
            while(count > 2 && didFind == false){

                let myRange = NSRange(location: count-1, length: 2)
                let substring = (orgString as NSString).substring(with: myRange)

//                print(substring,count)

                if substring == " w" || (substring  == "w." && count == 3){
                    didFind = true
//                    print("Did find",count)

                    var count2 = count
                    while(count2 < orgString.characters.count){

                        let myRange = NSRange(location: count2 - 1, length: 2)
                        let substring = (orgString as NSString).substring(with: myRange)

//                        print("Did 2",count2,substring)
                        count2 += 1


                        //If it was at the end of textView
                        if count2  == orgString.characters.count {

                            let length = orgString.characters.count - count
                            let myRange = NSRange(location: count, length: length)

                            let substring = (orgString as NSString).substring(with: myRange)

                            openLink(link: substring)
                            print("It's a Link",substring)
                            return
                        }

                        //If it's in the middle

                        if substring.hasSuffix(" "){

                            let length =  count2 - count
                            let myRange = NSRange(location: count, length: length)

                            let substring = (orgString as NSString).substring(with: myRange)

                            openLink(link: substring)
                            print("It's a Link",substring)

                            return
                        }

                    }

                    return
                }


                if substring.hasPrefix(" "){

                    print("Not a link")
                    return
                }

                count -= 1

            }


        }


    }


    func openLink(link:String){

        if let checkURL = URL(string: "http://\(link.replacingOccurrences(of: " ", with: ""))") {
            if UIApplication.shared.canOpenURL(checkURL) {
                UIApplication.shared.open(checkURL, options: [:], completionHandler: nil)

                print("url successfully opened")
            }
        } else {
            print("invalid url")
        }
    }


    public override func didMoveToWindow() {
        if self.window == nil{
            self.removeGestureRecognizer(tap)
            print("ClickableTextView View removed from")
        }
    }
}