【问题标题】:Detect hash tags #, mention tags @, in iOS like in Twitter App在 iOS 中检测哈希标签 #、提及标签 @,就像在 Twitter 应用程序中一样
【发布时间】:2014-08-13 03:24:25
【问题描述】:

我需要检测描述UILabel 中给出的#Tags 并将文本颜色更改为[UIColor BlueColor];,但我无法将UILabel 中的特定文本颜色更改为蓝色。现在我在自定义UITableViewCell 中使用这个UILabel。有没有办法解决这个问题,通过 Text Colors 区分 #Tags 和普通文本?谁能帮我解决这个问题?

【问题讨论】:

    标签: ios objective-c uitableview uilabel hashtag


    【解决方案1】:
    -(NSMutableAttributedString*)decorateTags:(NSString *)stringWithTags{
    
    
        NSError *error = nil;
    
        //For "Vijay #Apple Dev"
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"#(\\w+)" options:0 error:&error];
    
        //For "Vijay @Apple Dev"
        //NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"@(\\w+)" options:0 error:&error];
    
        NSArray *matches = [regex matchesInString:stringWithTags options:0 range:NSMakeRange(0, stringWithTags.length)];
        NSMutableAttributedString *attString=[[NSMutableAttributedString alloc] initWithString:stringWithTags];
    
        NSInteger stringLength=[stringWithTags length];
    
        for (NSTextCheckingResult *match in matches) {
    
            NSRange wordRange = [match rangeAtIndex:1];
    
            NSString* word = [stringWithTags substringWithRange:wordRange];
    
            //Set Font
            UIFont *font=[UIFont fontWithName:@"Helvetica-Bold" size:15.0f];
            [attString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, stringLength)];
    
    
            //Set Background Color
            UIColor *backgroundColor=[UIColor orangeColor];
            [attString addAttribute:NSBackgroundColorAttributeName value:backgroundColor range:wordRange];
    
            //Set Foreground Color
            UIColor *foregroundColor=[UIColor blueColor];
            [attString addAttribute:NSForegroundColorAttributeName value:foregroundColor range:wordRange];
    
            NSLog(@"Found tag %@", word);
    
        }
    
        // Set up your text field or label to show up the result
    
        //    yourTextField.attributedText = attString;
        //
        //    yourLabel.attributedText = attString;
    
        return attString;
    }
    

    【讨论】:

    • 嗨,Vijay,当我使用这个时,我觉得我在UITableView 中的滚动是有故障的。是因为将AttributedString 用于UILabel 吗?有什么想法吗?
    • 对 UILabel 使用 AttributedString 不会导致 tableview 出现故障。
    • 我觉得最好把所有的词都翻一遍,看看是#还是@开头的词。
    • 您只需为数据源数组执行一次并创建属性字符串,然后一次又一次地使用相同的字符串。这是最好的主意
    • 我喜欢这个方法的名字,–decorateTags:。 :)
    【解决方案2】:

    新: 在 iOS 9 中使用此链接https://github.com/hsusmita/ResponsiveLabel

    旧: 使用它也可以自定义https://github.com/SebastienThiebaud/STTweetLabel

    【讨论】:

    • 到现在为止有很大的bug,当你选择最后一个字符时它会崩溃。
    • 其中有什么问题? @FedeHenze
    • 它在 STTweetLabel github 页面中说不再支持该组件。我不建议使用不再受支持的组件。
    • @FedeHenze 请检查已编辑的答案。 +1 如果有帮助!
    • 我使用了 ActiveLabel github.com/optonaut/ActiveLabel.swift,但感谢您的更新!
    【解决方案3】:

    这是一个 Swift 解决方案。它使用UITextView,它支持属性文本、多行,并支持内置委托将点击事件映射到选定的单词(用户在看到蓝色文本时可能会期望)。

    它没有将字符范围更改为.blueColor(),而是添加了一个链接属性,该属性会自动将可点击文本设置为您的全局色调。

    它还包含对 Twitter 主题标签规则的一些基本支持,用于处理数字 #1 和特殊字符 @abc.go

    工作示例项目:

    https://github.com/ThornTechPublic/SwiftTextViewHashtag/blob/master/textViewSample/UITextField%2BExtension.swift

    具有更通用解释的博文:

    http://www.thorntech.com/2015/06/detecting-hashtags-mentions-and-urls-with-swift/

    extension UITextView {
    
        func chopOffNonAlphaNumericCharacters(text:String) -> String {
            var nonAlphaNumericCharacters = NSCharacterSet.alphanumericCharacterSet().invertedSet
            let characterArray = text.componentsSeparatedByCharactersInSet(nonAlphaNumericCharacters)
            return characterArray[0]
        }
    
        /// Call this manually if you want to hash tagify your string.
        func resolveHashTags(){
    
            let schemeMap = [
                "#":"hash",
                "@":"mention"
            ]
    
            // Turn string in to NSString.
            // NSString gives us some helpful API methods
            let nsText:NSString = self.text
    
            // Separate the string into individual words.
            // Whitespace is used as the word boundary.
            // You might see word boundaries at special characters, like before a period.
            // But we need to be careful to retain the # or @ characters.
            let words:[NSString] = nsText.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()) as! [NSString]
    
            // Attributed text overrides anything set in the Storyboard.
            // So remember to set your font, color, and size here.
            var attrs = [
    //            NSFontAttributeName : UIFont(name: "Georgia", size: 20.0)!,
    //            NSForegroundColorAttributeName : UIColor.greenColor(),
                NSFontAttributeName : UIFont.systemFontOfSize(17.0)
            ]
    
            // Use an Attributed String to hold the text and fonts from above.
            // We'll also append to this object some hashtag URLs for specific word ranges.
            var attrString = NSMutableAttributedString(string: nsText as String, attributes:attrs)
    
            // Iterate over each word.
            // So far each word will look like:
            // - I
            // - visited
            // - #123abc.go!
            // The last word is a hashtag of #123abc
            // Use the following hashtag rules:
            // - Include the hashtag # in the URL
            // - Only include alphanumeric characters.  Special chars and anything after are chopped off.
            // - Hashtags can start with numbers.  But the whole thing can't be a number (#123abc is ok, #123 is not)
            for word in words {
    
                var scheme:String? = nil
    
                if word.hasPrefix("#") {
                    scheme = schemeMap["#"]
                } else if word.hasPrefix("@") {
                    scheme = schemeMap["@"]
                }
    
                // found a word that is prepended by a hashtag
                if let scheme = scheme {
    
                    // convert the word from NSString to String
                    // this allows us to call "dropFirst" to remove the hashtag
                    var stringifiedWord:String = word as String
    
                    // example: #123abc.go!
    
                    // drop the hashtag
                    // example becomes: 123abc.go!
                    stringifiedWord = dropFirst(stringifiedWord)
    
                    // Chop off special characters and anything after them.
                    // example becomes: 123abc
                    stringifiedWord = chopOffNonAlphaNumericCharacters(stringifiedWord)
    
                    if let stringIsNumeric = stringifiedWord.toInt() {
                        // don't convert to hashtag if the entire string is numeric.
                        // example: 123abc is a hashtag
                        // example: 123 is not
                    } else if stringifiedWord.isEmpty {
                        // do nothing.
                        // the word was just the hashtag by itself.
                    } else {
                        // set a link for when the user clicks on this word.
                        var matchRange:NSRange = nsText.rangeOfString(stringifiedWord as String)
                        // Remember, we chopped off the hash tag, so:
                        // 1.) shift this left by one character.  example becomes:  #123ab
                        matchRange.location--
                        // 2.) and lengthen the range by one character too.  example becomes:  #123abc
                        matchRange.length++
                        // URL syntax is http://123abc
    
                        // Replace custom scheme with something like hash://123abc
                        // URLs actually don't need the forward slashes, so it becomes hash:123abc
                        // Custom scheme for @mentions looks like mention:123abc
                        // As with any URL, the string will have a blue color and is clickable
                        attrString.addAttribute(NSLinkAttributeName, value: "\(scheme):\(stringifiedWord)", range: matchRange)
                    }
                }
    
            }
    
            // Use textView.attributedText instead of textView.text
            self.attributedText = attrString
        }
    
    }
    

    用法:

    textView.resolveHashTags()
    

    处理点击事件:

    func showHashTagAlert(tagType:String, payload:String){
        let alertView = UIAlertView()
        alertView.title = "\(tagType) tag detected"
        // get a handle on the payload
        alertView.message = "\(payload)"
        alertView.addButtonWithTitle("Ok")
        alertView.show()
    }
    
    extension ViewController : UITextViewDelegate {
    
        func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool {
    
            // check for our fake URL scheme hash:helloWorld
            if let scheme = URL.scheme {
                switch scheme {
                case "hash" :
                    showHashTagAlert("hash", payload: URL.resourceSpecifier!)
                case "mention" :
                    showHashTagAlert("mention", payload: URL.resourceSpecifier!)
                default:
                    println("just a regular url")
                }
            }
    
            return true
        }
    
    }
    

    【讨论】:

      【解决方案4】:

      你可以使用https://github.com/Krelborn/KILabel这个库。它还检测用户对主题标签的点击 像这样:

      label.hashtagLinkTapHandler = ^(KILabel *label, NSString *string, NSRange range) {
        NSLog(@"Hashtag tapped %@", string);
      };
      

      【讨论】:

        猜你喜欢
        • 2012-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-01
        • 1970-01-01
        • 2012-09-08
        相关资源
        最近更新 更多