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

时间:2015-12-22 21:56:56

标签: ios swift uitextview

我正在尝试使用可点击的链接在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
}

以下是我实施的委托方法:

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

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

这仍然无效。我搜索过这个主题,但没有任何帮助。非常感谢提前。

3 个答案:

答案 0 :(得分:50)

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

enter image description here

答案 1 :(得分:1)

Swift 3 iOS 10:这是Clickable扩展的UITextView,可以自动检测textview中的网站,只要链接以 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")
        }
    }
}

答案 2 :(得分:1)

对于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
   }