![](/img/trans.png)
[英]How to detect and make hyperlinks/mentions/hashtags clickable in UILabel?
[英]How to make UITextView detect hashtags?
我知道UITextView
默認可以檢測 URL,但我怎樣才能讓它檢測主題標簽(#)?
它不需要在鍵入時檢測主題標簽,但是viewDidLoad
文本在UITextView
中設置,所以我想將主題標簽檢測為顏色或其他東西。
我一直在使用ActiveLabel ,但這僅適用於UILabel
,我需要UITextView
具有的滾動功能。
UITextViewHashtagExtension.swift
)在下面插入此代碼:
import UIKit extension UITextView { func resolveHashTags(){ // turn string in to NSString let nsText:NSString = self.text // this needs to be an array of NSString. String does not work. let words:[NSString] = nsText.componentsSeparatedByString(" ") // you can't set the font size in the storyboard anymore, since it gets overridden here. let attrs = [ NSFontAttributeName : UIFont.systemFontOfSize(17.0) ] // you can staple URLs onto attributed strings let attrString = NSMutableAttributedString(string: nsText as String, attributes:attrs) // tag each word if it has a hashtag for word in words { // found a word that is prepended by a hashtag! // homework for you: implement @mentions here too. if word.hasPrefix("#") { // a range is the character position, followed by how many characters are in the word. // we need this because we staple the "href" to this range. let matchRange:NSRange = nsText.rangeOfString(word as String) // convert the word from NSString to String // this allows us to call "dropFirst" to remove the hashtag var stringifiedWord:String = word as String // drop the hashtag stringifiedWord = String(stringifiedWord.characters.dropFirst()) // check to see if the hashtag has numbers. // ribl is "#1" shouldn't be considered a hashtag. let digits = NSCharacterSet.decimalDigitCharacterSet() if let numbersExist = stringifiedWord.rangeOfCharacterFromSet(digits) { // hashtag contains a number, like "#1" // so don't make it clickable } else { // set a link for when the user clicks on this word. // it's not enough to use the word "hash", but you need the url scheme syntax "hash://" // note: since it's a URL now, the color is set to the project's tint color attrString.addAttribute(NSLinkAttributeName, value: "hash:\(stringifiedWord)", range: matchRange) } } } // we're used to textView.text // but here we use textView.attributedText // again, this will also wipe out any fonts and colors from the storyboard, // so remember to re-add them in the attrs dictionary above self.attributedText = attrString } }
要使用它,您可以執行以下操作:
self.textView.text = "This is an #example test"
self.textView.resolveHashTags()
為 Swift 4.0 更新:
extension UITextView {
func resolveHashTags() {
// turn string in to NSString
let nsText = NSString(string: self.text)
// this needs to be an array of NSString. String does not work.
let words = nsText.components(separatedBy: CharacterSet(charactersIn: "#ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_").inverted)
// you can staple URLs onto attributed strings
let attrString = NSMutableAttributedString()
attrString.setAttributedString(self.attributedText)
// tag each word if it has a hashtag
for word in words {
if word.count < 3 {
continue
}
// found a word that is prepended by a hashtag!
// homework for you: implement @mentions here too.
if word.hasPrefix("#") {
// a range is the character position, followed by how many characters are in the word.
// we need this because we staple the "href" to this range.
let matchRange:NSRange = nsText.range(of: word as String)
// drop the hashtag
let stringifiedWord = word.dropFirst()
if let firstChar = stringifiedWord.unicodeScalars.first, NSCharacterSet.decimalDigits.contains(firstChar) {
// hashtag contains a number, like "#1"
// so don't make it clickable
} else {
// set a link for when the user clicks on this word.
// it's not enough to use the word "hash", but you need the url scheme syntax "hash://"
// note: since it's a URL now, the color is set to the project's tint color
attrString.addAttribute(NSAttributedStringKey.link, value: "hash:\(stringifiedWord)", range: matchRange)
}
}
}
// we're used to textView.text
// but here we use textView.attributedText
// again, this will also wipe out any fonts and colors from the storyboard,
// so remember to re-add them in the attrs dictionary above
self.attributedText = attrString
}
}
一種選擇是使用NSAttributedString
,像這樣......
func convertHashtags(text:String) -> NSAttributedString {
let attrString = NSMutableAttributedString(string: text)
attrString.beginEditing()
// match all hashtags
do {
// Find all the hashtags in our string
let regex = try NSRegularExpression(pattern: "(?:\\s|^)(#(?:[a-zA-Z].*?|\\d+[a-zA-Z]+.*?))\\b", options: NSRegularExpressionOptions.AnchorsMatchLines)
let results = regex.matchesInString(text,
options: NSMatchingOptions.WithoutAnchoringBounds, range: NSMakeRange(0, text.characters.count))
let array = results.map { (text as NSString).substringWithRange($0.range) }
for hashtag in array {
// get range of the hashtag in the main string
let range = (attrString.string as NSString).rangeOfString(hashtag)
// add a colour to the hashtag
attrString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor() , range: range)
}
attrString.endEditing()
}
catch {
attrString.endEditing()
}
return attrString
}
然后像這樣分配您的attributedText
文本...
let myText = "some text with a #hashtag in side of it #itsnoteasy"
self.textView.attributedText = convertHashtags(myText)
對於 Swift 4.0
extension UITextView {
func resolveHashTags() {
// turn string in to NSString
let nsText = NSString(string: self.text)
// this needs to be an array of NSString. String does not work.
let words = nsText.components(separatedBy: CharacterSet(charactersIn: "#ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_").inverted)
// you can staple URLs onto attributed strings
let attrString = NSMutableAttributedString()
attrString.setAttributedString(self.attributedText)
// tag each word if it has a hashtag
for word in words {
if word.count < 3 {
continue
}
// found a word that is prepended by a hashtag!
// homework for you: implement @mentions here too.
if word.hasPrefix("#") {
// a range is the character position, followed by how many characters are in the word.
// we need this because we staple the "href" to this range.
let matchRange:NSRange = nsText.range(of: word as String)
// drop the hashtag
let stringifiedWord = word.dropFirst()
if let firstChar = stringifiedWord.unicodeScalars.first, NSCharacterSet.decimalDigits.contains(firstChar) {
// hashtag contains a number, like "#1"
// so don't make it clickable
} else {
// set a link for when the user clicks on this word.
// it's not enough to use the word "hash", but you need the url scheme syntax "hash://"
// note: since it's a URL now, the color is set to the project's tint color
attrString.addAttribute(NSAttributedStringKey.link, value: "hash:\(stringifiedWord)", range: matchRange)
}
}
}
// we're used to textView.text
// but here we use textView.attributedText
// again, this will also wipe out any fonts and colors from the storyboard,
// so remember to re-add them in the attrs dictionary above
self.attributedText = attrString
}
}
對於 Swift 3 +
extension UITextView {
func convertHashtags(text:String) -> NSAttributedString {
let attr = [
NSFontAttributeName : UIFont.systemFont(ofSize: 17.0),
NSForegroundColorAttributeName : clr_golden,
NSLinkAttributeName : "https://Laitkor.com"
] as [String : Any]
let attrString = NSMutableAttributedString(string: text)
attrString.beginEditing()
// match all hashtags
do {
// Find all the hashtags in our string
let regex = try NSRegularExpression(pattern: "(?:\\s|^)(#(?:[a-zA-Z].*?|\\d+[a-zA-Z]+.*?))\\b", options: NSRegularExpression.Options.anchorsMatchLines)
let results = regex.matches(in: text,
options: NSRegularExpression.MatchingOptions.withoutAnchoringBounds, range: NSMakeRange(0, text.characters.count))
let array = results.map { (text as NSString).substring(with: $0.range) }
for hashtag in array {
// get range of the hashtag in the main string
let range = (attrString.string as NSString).range(of: hashtag)
// add a colour to the hashtag
//attrString.addAttribute(NSForegroundColorAttributeName, value: clr_golden , range: range)
attrString.addAttributes(attr, range: range)
}
attrString.endEditing()
}
catch {
attrString.endEditing()
}
return attrString
}
}
在您的班級中添加 UITextViewDelegate 並像這樣使用
self.tv_yourTextView.delegate = self
self.tv_yourTextView.attributedText = tv_yourTextView.convertHashtags(text: "This is an #museer test")
委托功能
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
print("hastag Selected!")
return true
}
-> 修改@Wez 答案
何時提及或標簽或任何詞,您可以通過以下方式進行:
func convertRegex(文本:字符串,正則表達式:字符串)-> NSAttributedString {
let attr:[NSAttributedString.Key:Any] = [
NSAttributedString.Key.font : UIFont.systemFont(ofSize: 17.0),
NSAttributedString.Key.foregroundColor : UIColor.green,
] as [NSAttributedString.Key : Any]
let attrString = NSMutableAttributedString(string: text)
attrString.beginEditing()
do {
// Find all the specific word in our string
let regex = try NSRegularExpression(pattern: "\\s\(regex)\\b" , options: NSRegularExpression.Options.anchorsMatchLines)
let results = regex.matches(in: text,
options: NSRegularExpression.MatchingOptions.withoutAnchoringBounds, range: NSMakeRange(0, text.count))
let array = results.map { (text as NSString).substring(with: $0.range) }
for word in array {
let range = (attrString.string as NSString).range(of: word)
attrString.addAttributes(attr, range: range)
}
attrString.endEditing()
}
catch {
attrString.endEditing()
}
return attrString
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.