I need to Detect #Tags given in description UILabel
and change text color as [UIColor BlueColor];
where i am not able to change particular text colors in UILabel
to Blue. Now i am Using this UILabel
in custom UITableViewCell
. is there any way to solve this issue to differentiate #Tags and normal text by Text Colors ? can anybody help me to solve this ?
问题:
回答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;
}
回答2:
New : Use this link in iOS 9 https://github.com/hsusmita/ResponsiveLabel
Old : Use this Its customizable as well https://github.com/SebastienThiebaud/STTweetLabel
回答3:
Here's a Swift solution. It uses UITextView
which supports attributed text, multiline, and supports the built-in delegate to map tap events to the selected words (which users might expect when they see blue text).
Rather than changing the range of characters to .blueColor()
, it adds a link attribute which automatically sets the clickable text to your global tint.
It also contains some basic support for Twitter hashtag rules for handling numbers #1
and special characters @abc.go
.
Working sample project:
https://github.com/ThornTechPublic/SwiftTextViewHashtag/blob/master/textViewSample/UITextField%2BExtension.swift
Blog post with a more generic explanation:
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
}
}
Usage:
textView.resolveHashTags()
To handle the tap event:
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:
You can use https://github.com/Krelborn/KILabel this library. It also detect user taps on hashtags Like this:
label.hashtagLinkTapHandler = ^(KILabel *label, NSString *string, NSRange range) {
NSLog(@"Hashtag tapped %@", string);
};