0

If I use the same function below to set some attributes for an attributed string with a UILabel and a UITextView then the display looks the same in both cases, but I can't tap on the links for the UILabel (User Interaction is enabled for it).

Why doesn't the UILabel respond to taps but the UITextVIew does, how to enable the UILabel to behave like the UITextVIew?

I saw a past question and the answer was to set dataDetectors for the UILabel, but that must have been for an old version of Swift as it doesn't exist anymore and I didn't see anything similar as an alternative.

class MyViewController: UIViewController {

    @IBOutlet weak var label1: UILabel!
    @IBOutlet weak var textView1: UITextView!

    let kTextContent = "This is some text with bold and link1 and link2 and color."
    let kBoldText = "bold"
    let kLink1Text = "link1"
    let kLink2Text = "link2"
    let kColorText = "color"
    let kUrl1 = "http://www.google.com"
    let kUrl2 = "http://www.apple.com"

    override func viewDidLoad() {
        super.viewDidLoad()

        label1.text = kTextContent
        label1.attributedText = setAttributes(theAttributedString: label1.attributedText?.mutableCopy(with: nil) as! NSMutableAttributedString)

        textView1.text = kTextContent
        textView1.attributedText = setAttributes(theAttributedString: textView1.attributedText?.mutableCopy(with: nil) as! NSMutableAttributedString)
    }

    func setAttributes(theAttributedString: NSMutableAttributedString) -> NSMutableAttributedString
    {
        let boldRange = theAttributedString.mutableString.range(of: kBoldText)
        let boldFontAttribute: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 20)]
        theAttributedString.addAttributes(boldFontAttribute, range: boldRange)

        let link1Range = theAttributedString.mutableString.range(of: kLink1Text)
        theAttributedString.addAttribute(.link, value: kUrl1, range: link1Range)
        theAttributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: link1Range)

        let link2Range = theAttributedString.mutableString.range(of: kLink2Text)
        theAttributedString.addAttribute(NSAttributedString.Key.link, value: kUrl2, range: link2Range)
        theAttributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: link2Range)

        let colorRange = theAttributedString.mutableString.range(of: kColorText)
        theAttributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red , range: colorRange)

        return theAttributedString
    }
user9435893
  • 65
  • 1
  • 7
  • https://stackoverflow.com/questions/55826193/swift-the-html-data-converted-to-nsattributed-string-doesnt-make-the-links-cli/55857598#55857598 – Larme May 03 '19 at 15:38
  • It's normal behavior from the start of iOS. See link related answer where I explained why, and definitely look at the WWDC Video. – Larme May 03 '19 at 15:44

1 Answers1

0

A UILabel that responds to taps is a UIButton, I suggest that you swap out your UILabel for a button and style it accordingly. Then you can just hook up an IBAction to it and it'll work.

UITextView responds to interaction by default

Mr.P
  • 1,390
  • 13
  • 35
  • But a button graphically looks nothing like a UILabel. Do you mean give the button transparent boarder and background etc. – user9435893 May 03 '19 at 15:39
  • Yes that's exactly what I mean. You can also add a `UITapGesture` to the `UILabel`, but you are technically just recreating a `UIButton` – Mr.P May 03 '19 at 15:40
  • There are two different URL links, how would that be dealt with by making the entire text a single button? – user9435893 May 03 '19 at 15:41
  • @user9435893 Read my answer on related question. I gave explaination on why it doesn't work, how to make it work, and what's recommended by Apple. But what you are seeing is normal behavior. – Larme May 03 '19 at 15:42