LoginSignup
2
1

More than 5 years have passed since last update.

UILabelのテキストの一部をハイパーリンク化

Posted at

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

Purpose

Personal Note

Development Environment

  • OS X El Captain 10.11.2
  • Xcode Version 8.0

Language

Swift 3.0

Code

    @IBOutlet weak var yourLabel: UILabel!
    var targetRect: CGRect = CGRect()
    // Hyper Link
    func setHyperLink(hyperlinkText: String){
        let text = "Hello Qiita Hello Law Hello Guys"

        yourLabel.backgroundColor = UIColor.clear
        yourLabel.textAlignment = .left

        let nsText = text as NSString
        let linkRange = text.range(of: hyperlinkText)

        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 = hyperlinkText.characters.count
        let firstRange = NSMakeRange(firstStart, firstLength)
        let boldFontAttribute = [NSFontAttributeName: UIFont.boldSystemFont(ofSize: 13.0)]

        // all text colour
        attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.black, range: NSMakeRange(0, nsText.length))
        // link colour
        attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.black, range: firstRange)
        attributedString.addAttributes(boldFontAttribute, range: firstRange)
        yourLabel.attributedText = attributedString

        yourLabel.isUserInteractionEnabled = true
        targetRect = getRect(str: yourLabel.attributedText!, range: firstRange, width: yourLabel.frame.width)
        yourLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapText(sender:))))
    }

    func getRect(str: NSAttributedString, range: NSRange, width: CGFloat) -> CGRect {
        let storage = NSTextStorage(attributedString: str)
        let container = NSTextContainer(size: CGSize(width: width, height: CGFloat.greatestFiniteMagnitude))
        let layoutManager = NSLayoutManager()
        layoutManager.addTextContainer(container)
        storage.addLayoutManager(layoutManager)
        container.lineFragmentPadding = 0
        let pointer = UnsafeMutablePointer<NSRange>.allocate(capacity: 1)
        layoutManager.characterRange(forGlyphRange: range, actualGlyphRange: pointer)
        return layoutManager.boundingRect(forGlyphRange: pointer.move(), in: container)
    }

    func tapText(sender: UITapGestureRecognizer) {
        if targetRect.contains(sender.location(in: sender.view)) {
            // add your action from here
        }
    }

However, this code is not compatible with Emoji... counting emoji characters is still problematic.

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1