当前位置: > > > Swift - 给UITextView添加自定义链接,以及链接的点击响应

Swift - 给UITextView添加自定义链接,以及链接的点击响应

(本文代码已升级只Swift3)

我们知道多行文本框(UITextView)具有URL检测功能,将其开启后,它会高亮显示内容中的url链接文字,点击后会使用safari打开这个链接。
        

1,让textView支持自定义链接
除了能够用浏览器打开url链接外,有时我们还想让内容中的链接能实现一些个性化的功能需求。比如:点击“查看详细说明”后,APP会跳转到功能说明页面。而点击“问题反馈”链接时,又会到进行问题反馈操作。
            

2,实现原理:
(1)对于这些特殊的链接我们使用自定义的一些 URL scheme 来表示。比如:about:代表详细说明,feedback:代表问题反馈。
(2)通过拼接 NSMutableAttributedString 的方式,将各个带链接属性、不带链接属性的文本拼接起来,赋值给textview。
(3)使用textview的 UITextFieldDelegate 代理的 shouldInteractWithURL 方法,我们可以捕获到这些自定义的URL scheme点击,然后通过判断 URL.scheme 来执行不同的操作。

3,实现步骤
(1)对于用来显示的textview,要将其 Detection Links(链接检测)打勾,去掉 Editable(使其不可编辑)。

(2)为方便使用,扩展UITextView:
extension UITextView {
    //添加链接文本(链接为空时则表示普通文本)
    func appendLinkString(string:String, withURLString:String = "") {
        //原来的文本内容
        let attrString:NSMutableAttributedString = NSMutableAttributedString()
        attrString.append(self.attributedText)
        
        //新增的文本内容(使用默认设置的字体样式)
        let attrs = [NSFontAttributeName : self.font!]
        let appendString = NSMutableAttributedString(string: string, attributes:attrs)
        //判断是否是链接文字
        if withURLString != "" {
            let range:NSRange = NSMakeRange(0, appendString.length)
            appendString.beginEditing()
            appendString.addAttribute(NSLinkAttributeName, value:withURLString, range:range)
            appendString.endEditing()
        }
        //合并新的文本
        attrString.append(appendString)
        
        //设置合并后的文本
        self.attributedText = attrString
    }
}

(3)样例代码 :
import UIKit

class ViewController: UIViewController, UITextViewDelegate  {

    @IBOutlet weak var textView: UITextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //设置展示文本框的代理
        textView.delegate = self
        
        textView.text = ""
        textView.appendLinkString(string: "欢迎使用航歌APP!\n")
        textView.appendLinkString(string: "(1)")
        textView.appendLinkString(string: "查看详细说明", withURLString: "about:from123")
        textView.appendLinkString(string: "\n(2)")
        textView.appendLinkString(string: "问题反馈", withURLString: "feedback:from234")
    }
    
    //链接点击响应方法
    func textView(_ textView: UITextView, shouldInteractWith URL: URL,
                  in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
        if let scheme = URL.scheme {
            switch scheme {
            case "about" :
                showAlert(tagType: "about",
                          payload: (URL as NSURL).resourceSpecifier!.removingPercentEncoding!)
            case "feedback" :
                showAlert(tagType: "feedback",
                          payload: (URL as NSURL).resourceSpecifier!.removingPercentEncoding!)
            default:
                print("这个是普通的url")
            }
        }
        
        return true
    }
    
    //显示消息
    func showAlert(tagType:String, payload:String){
        let alertController = UIAlertController(title: "检测到\(tagType)标签",
            message: payload, preferredStyle: .alert)
        let cancelAction = UIAlertAction(title: "确定", style: .cancel, handler: nil)
        alertController.addAction(cancelAction)
        self.present(alertController, animated: true, completion: nil)
    }
}
评论2
  • 2楼
    2017-04-26 17:00
    爱闯祸的小乾乾

    请问这种情况下怎么在URL下添加下划线啊?能不能只通过Xib单纯地设置一下?如果不能的话,有没有什么好的方法添加下划线,希望能看到我的问题~谢谢~

    站长回复

    可以参考我写的这篇文章:Swift - 修改UITextView中链接的样式(链接颜色、下划线样式)

  • 1楼
    2016-08-20 12:30
    Kimi

    請問航歌,textview偵測到了URL,其URL內容為一張圖片,是直接調用NSURLSession把圖片載回來,再新增文本內容,然後顯示出來嗎?
    我在做一個類似Blog的顯示方式,一直抓不到要領

    站长回复

    是这样做的,你要把先把图片url都给提取出来,接着加载图片,最后把图片和文字一起再加载到textView中。

    图文混排的话可以参考我之前写的这篇文章:Swift - 文本框textView图文混排的实现(附样例)