ios - 如何让 UITextView 检测主题标签?

标签 ios swift uitextview

我知道 UITextView 默认可以检测 URL,但我怎样才能让它检测到 hashtags(#)?

它不需要在打字时检测主题标签,但是 viewDidLoad 文本设置在 UITextView 中,所以我想检测主题标签作为颜色或其他东西.

我一直在使用ActiveLabel ,但这仅适用于 UILabel,我需要 UITextView 具有的滚动功能。

最佳答案

这应该适合你

  1. 创建一个任意名称的新 swift 文件(UITextViewHashtagExtension.swift)
  2. 在下面插入这段代码:

    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
    }
}

关于ios - 如何让 UITextView 检测主题标签?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34294064/

相关文章:

ios - 防止在 shouldChangeTextInRange 期间删除前缀

objective-c - 访问应用程序包中的 plist 返回 null

ios - iPhone在后台播放图层动画时崩溃

objective-c - 尝试将面子书登录按钮移植到 swift

xcode - 在uitextview中选择文本时,应用程序崩溃

即使在安装 "Xcode Version 11.2.1 (11B500)"后,Xcode 仍会导致使用 UITextView 的应用程序崩溃

iphone - 我们如何才能释放我们不再使用它的 View ?

ios - 从 Storyboard 设置 IBAction 时获取 'Touch Drag Inside' 距离

swift - 如何以编程方式向我的 UILabel 添加约束

iOS 8 : how to set height programmatically for a UITableview in a freeform ViewController