UITextViewの特定の文字をハイパーリンク化してみた。(Swift 3.0対応)


This post is about how to make hyperlink of words in UITextView.

Purpose

Personal Note

Development Environment

  • OS X El Captain 10.11.2
  • Xcode Version 8.0

Language

Swift 3.0

Step

1- import UIKit to activate the library to use

import UIKit

2- Declare a parameter of firstRange

var firstRange: NSRange = NSRange()

3- Create main two functions (1. Decorate words / 2. Tap Action)

    func setHyperLink(targetText: String){
        let text = "Hello Qiita Hello Law Hello Guys"

        yourTextView.backgroundColor = UIColor.clear

        yourTextView.textAlignment = .left

        let nsTex = text as NSString
        let linkRange = text.range(of: targetText)

        let style = NSMutableParagraphStyle()
        style.alignment = NSTextAlignment.left

        let attributedString = NSMutableAttributedString(string: text, attributes: [ NSParagraphStyleAttributeName: style ])

        let firstStart = text.distance(from: text.startIndex, to: linkRange!.lowerBound)
        let firstLength = targetText.characters.count
        firstRange = NSMakeRange(firstStart, firstLength)
        let boldFontAttribute = [NSFontAttributeName: UIFont.boldSystemFont(ofSize: 13.0)]


        /*リンク位置範囲生成*/
        // all text colour
        attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.black, range: NSMakeRange(0, nsTex.length))
        // link colour
        attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.black, range: firstRange)
        attributedString.addAttributes(boldFontAttribute, range: firstRange)

        yourTextView.attributedText = attributedString

        let firstTap = UITapGestureRecognizer(target: self, action: #selector(self.tapText(tap:)))
        yourTextView.addGestureRecognizer(firstTap)

    }

    func tapText(tap: UITapGestureRecognizer) {
        let location = tap.location(in: yourTextView)
        let textPosition = yourTextView.closestPosition(to: location)
        let selectedPosition = yourTextView.offset(from: yourTextView.beginningOfDocument, to: textPosition!)
        if NSLocationInRange(selectedPosition, firstRange) {
            // Add your action. For Example, navigating to another page
            print("You tapped")
        }
    }
}

4- Done

Source Code

ViewController.swift
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var yourTextView: UITextView!

    var firstRange: NSRange = NSRange()

    override func viewDidLoad() {
        super.viewDidLoad()
        yourTextView.isEditable = false
        setHyperLink(targetText: "Law")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

/* Function */
extension ViewController{
    // Hyper Link
    func setHyperLink(targetText: String){
        let text = "Hello Qiita Hello Law Hello Guys"

        yourTextView.backgroundColor = UIColor.clear

        yourTextView.textAlignment = .left

        let nsTex = text as NSString
        let linkRange = text.range(of: targetText)

        let style = NSMutableParagraphStyle()
        style.alignment = NSTextAlignment.left

        let attributedString = NSMutableAttributedString(string: text, attributes: [ NSParagraphStyleAttributeName: style ])

        let firstStart = text.distance(from: text.startIndex, to: linkRange!.lowerBound)
        let firstLength = targetText.characters.count
        firstRange = NSMakeRange(firstStart, firstLength)
        let boldFontAttribute = [NSFontAttributeName: UIFont.boldSystemFont(ofSize: 13.0)]


        /*リンク位置範囲生成*/
        // all text colour
        attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.black, range: NSMakeRange(0, nsTex.length))
        // link colour
        attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.black, range: firstRange)
        attributedString.addAttributes(boldFontAttribute, range: firstRange)

        yourTextView.attributedText = attributedString

        let firstTap = UITapGestureRecognizer(target: self, action: #selector(self.tapText(tap:)))
        yourTextView.addGestureRecognizer(firstTap)

    }

    func tapText(tap: UITapGestureRecognizer) {
        let location = tap.location(in: yourTextView)
        let textPosition = yourTextView.closestPosition(to: location)
        let selectedPosition = yourTextView.offset(from: yourTextView.beginningOfDocument, to: textPosition!)
        if NSLocationInRange(selectedPosition, firstRange) {
            // Add your action. For Example, navigating to another page
            print("You tapped")
        }
    }
}

Conclusion

The code is quite simple and if you understand how to use Range, you can apply in another way.