简体   繁体   中英

how can I make hashtags clickable in UILabel in Swift 3?

In my application I created an extension to UILabel that contains the following method:

func formatTextInLabel() {
    let text = self.text
    let font = UIFont(name: fontName, size: 16.0)
    let titleDict: NSDictionary = [NSFontAttributeName: font!]
    // This will give me an attributedString with the desired font
    let attributedString = NSMutableAttributedString(string: text!, attributes: titleDict as! [String : AnyObject])
    let regex = try? NSRegularExpression(pattern: "#(\\w+)", options: [])
    let matches = regex!.matches(in: text!, options: [], range: NSMakeRange(0, text!.characters.count))
    for match in matches {
        let matchRange = match.rangeAt(0)

        let titleDict: NSDictionary = [NSForegroundColorAttributeName: orangeColor]

        attributedString.addAttributes(titleDict as! [String : AnyObject], range: matchRange)
    }
    self.attributedText = attributedString
}

and it highlights all #hashtags in my chosen color. But they are not clickable, I found some post on SO that says it's impossible to achieve: How to detect and make hyperlinks/mentions/hashtags clickable in UILabel? but it seems to be outdated (hopefully). Can you give me a hint how can I eg display in the console the name of selected hashtag?

One more thing to add - I'm aware of some pod s like ActiveLabel or similar, but I tried them and had problems with constraints in my case, so I want to achieve this effect from my own code.

Try adding a UITapGestureRecognizer to the label:

let tap = UITapGestureRecognizer(target: self, action: #selector(handleLabelTap(_:)))
label.addGestureRecognizer(tap)

func handleLabelTap(_ sender: UITapGestureRecognizer) {

    // Do something here for when the user taps on the label

}

For that to work, you probably have to set isUserInteractionEnabled to true on for the label. I just did a test in Xcode and it worked. So:

label.isUserInteractionEnabled = true

EDIT:

If you want to determine which hashtag has been tapped, at the top of your class declaration, before it's initialized create properties for an empty UILabel array, and an empty UITapGestureRecognizer array like this:

var labels:[UILabel] = [UILabel]()
var labelTaps:[UITapGestureRecognizer] = [UITapGestureRecognizer]()

Then when you create each label append the label and the tap gesture to each respective array

let label = UILabel()
// Set all label properties as you wish

// Make sure to add
label.isUserInteractionEnabled = true

// Create the tap gesture
let tap = UITapGestureRecognizer(target: self, action: #selector(handleLabelTap(_:)))
label.addGestureRecognizer(tap)

labels.append(label)
labelTaps.append(tap)

Then when a user taps on one of the hash-tags, you can get the index of which tap gesture was sent to the method, and then use that to figure out which label it is because it would have the same index in the 'labels' array as it's respective gesture recognizer would have in the 'labelTaps' array. Here is how you do that:

func handleLabelTap(_ sender: UITapGestureRecognizer) {

    if let index = labelTaps.index(of: sender) {

        let tappedLabel:UILabel = labels[index]

        // Now you can do whatever you want
        print("User tapped label with hash-tag: \(tappedLabel.text)")

    }

}

You can't make links clickable in a UILabel , but you can in a UITextField or UITextView . Those allow adding clickable links.

If the link is displayed as a link, like http://address@domain.com then you can simply turn on link detection. If you want the link to display an arbitrary string like "click here" and make that string clickable you'll need to install an attributed string into the text field/text view.

What type of links are these, and what do you want it to look like in the text?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM