你如何使用NSAttributedString?

NSStringNSMutableStrings中的多种颜色是不可能的。 所以我听说了一些关于在iPad SDK 3.2 (或者大约3.2)中引入的NSAttributedString ,并且在iPhone SDK 4.0 beta版本iPhone上可用。

我想要一个有三种颜色的string。

我不使用3个单独的NSString的原因是因为三个NSAttributedString子串中的每一个的长度经常变化,所以我宁愿不使用任何计算来重新定位3个单独的NSString对象。

如果有可能使用NSAttributedString我怎么做以下 – (如果不可能与NSAttributedstring,你会怎么做):

替代文字

编辑:请记住, @"first"@"second"@"third"将随时被其他stringreplace。 所以使用硬编码的NSRange值将不起作用。

在构build属性string时,我更喜欢使用可变子类,只是为了保持清洁。

这就是说,这是如何创build一个三色的属性string:

 NSMutableAttributedString * string = [[NSMutableAttributedString alloc] initWithString:@"firstsecondthird"]; [string addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0,5)]; [string addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(5,6)]; [string addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(11,5)]; 

在浏览器中键入。 警告实施者

显然你不会在这样的范围内硬编码。 也许你可以做一些事情:

 NSDictionary * wordToColorMapping = ....; //an NSDictionary of NSString => UIColor pairs NSMutableAttributedString * string = [[NSMutableAttributedString alloc] initWithString:@""]; for (NSString * word in wordToColorMapping) { UIColor * color = [wordToColorMapping objectForKey:word]; NSDictionary * attributes = [NSDictionary dictionaryWithObject:color forKey:NSForegroundColorAttributeName]; NSAttributedString * subString = [[NSAttributedString alloc] initWithString:word attributes:attributes]; [string appendAttributedString:subString]; [subString release]; } //display string 

这个问题已经得到了解答,但是我想要展示如何添加阴影并使用NSAttributedString更改字体,这样当人们search这个主题时,他们就不用再继续寻找了。

 #define FONT_SIZE 20 #define FONT_HELVETICA @"Helvetica-Light" #define BLACK_SHADOW [UIColor colorWithRed:40.0f/255.0f green:40.0f/255.0f blue:40.0f/255.0f alpha:0.4f] NSString*myNSString = @"This is my string.\nIt goes to a second line."; NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.alignment = NSTextAlignmentCenter; paragraphStyle.lineSpacing = FONT_SIZE/2; UIFont * labelFont = [UIFont fontWithName:FONT_HELVETICA size:FONT_SIZE]; UIColor * labelColor = [UIColor colorWithWhite:1 alpha:1]; NSShadow *shadow = [[NSShadow alloc] init]; [shadow setShadowColor : BLACK_SHADOW]; [shadow setShadowOffset : CGSizeMake (1.0, 1.0)]; [shadow setShadowBlurRadius : 1]; NSAttributedString *labelText = [[NSAttributedString alloc] initWithString : myNSString attributes : @{ NSParagraphStyleAttributeName : paragraphStyle, NSKernAttributeName : @2.0, NSFontAttributeName : labelFont, NSForegroundColorAttributeName : labelColor, NSShadowAttributeName : shadow }]; 

这是一个Swift版本…

警告! 这适用于4秒。

对于5秒,你必须将所有的浮点数值改为双精度值(因为编译器工作不正常)

Swift enum字体select:

 enum FontValue: Int { case FVBold = 1 , FVCondensedBlack, FVMedium, FVHelveticaNeue, FVLight, FVCondensedBold, FVLightItalic, FVUltraLightItalic, FVUltraLight, FVBoldItalic, FVItalic } 

用于枚举访问的Swift数组(因为枚举不能使用“ – ”):

 func helveticaFont (index:Int) -> (String) { let fontArray = [ "HelveticaNeue-Bold", "HelveticaNeue-CondensedBlack", "HelveticaNeue-Medium", "HelveticaNeue", "HelveticaNeue-Light", "HelveticaNeue-CondensedBold", "HelveticaNeue-LightItalic", "HelveticaNeue-UltraLightItalic", "HelveticaNeue-UltraLight", "HelveticaNeue-BoldItalic", "HelveticaNeue-Italic", ] return fontArray[index] } 

Swift归因于文本function:

 func myAttributedText (myString:String, mySize: Float, myFont:FontValue) -> (NSMutableAttributedString) { let shadow = NSShadow() shadow.shadowColor = UIColor.textShadowColor() shadow.shadowOffset = CGSizeMake (1.0, 1.0) shadow.shadowBlurRadius = 1 let paragraphStyle = NSMutableParagraphStyle.alloc() paragraphStyle.lineHeightMultiple = 1 paragraphStyle.lineBreakMode = NSLineBreakMode.ByWordWrapping paragraphStyle.alignment = NSTextAlignment.Center let labelFont = UIFont(name: helveticaFont(myFont.toRaw()), size: mySize) let labelColor = UIColor.whiteColor() let myAttributes :Dictionary = [NSParagraphStyleAttributeName : paragraphStyle, NSKernAttributeName : 3, // (-1,5) NSFontAttributeName : labelFont, NSForegroundColorAttributeName : labelColor, NSShadowAttributeName : shadow] let myAttributedString = NSMutableAttributedString (string: myString, attributes:myAttributes) // add new color let secondColor = UIColor.blackColor() let stringArray = myString.componentsSeparatedByString(" ") let firstString: String? = stringArray.first let letterCount = countElements(firstString!) if firstString { myAttributedString.addAttributes([NSForegroundColorAttributeName:secondColor], range:NSMakeRange(0,letterCount)) } return myAttributedString } 

用于在string数组中查找范围的第一个和最后一个扩展:

 extension Array { var last: T? { if self.isEmpty { NSLog("array crash error - please fix") return self [0] } else { return self[self.endIndex - 1] } } } extension Array { var first: T? { if self.isEmpty { NSLog("array crash error - please fix") return self [0] } else { return self [0] } } } 

新颜色:

 extension UIColor { class func shadowColor() -> UIColor { return UIColor(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, alpha: 0.3) } class func textShadowColor() -> UIColor { return UIColor(red: 50.0/255.0, green: 50.0/255.0, blue: 50.0/255.0, alpha: 0.5) } class func pastelBlueColor() -> UIColor { return UIColor(red: 176.0/255.0, green: 186.0/255.0, blue: 255.0/255.0, alpha: 1) } class func pastelYellowColor() -> UIColor { return UIColor(red: 255.0/255.0, green: 238.0/255.0, blue: 140.0/255.0, alpha: 1) } } 

我的macros代替:

 enum MyConstants: Float { case CornerRadius = 5.0 } 

我的button制造商瓦特/归属文字:

 func myButtonMaker (myView:UIView) -> UIButton { let myButton = UIButton.buttonWithType(.System) as UIButton myButton.backgroundColor = UIColor.pastelBlueColor() myButton.showsTouchWhenHighlighted = true; let myCGSize:CGSize = CGSizeMake(100.0, 50.0) let myFrame = CGRectMake(myView.frame.midX - myCGSize.height,myView.frame.midY - 2 * myCGSize.height,myCGSize.width,myCGSize.height) myButton.frame = myFrame let myTitle = myAttributedText("Button",20.0,FontValue.FVLight) myButton.setAttributedTitle(myTitle, forState:.Normal) myButton.layer.cornerRadius = myButton.bounds.size.width / MyConstants.CornerRadius.toRaw() myButton.setTitleColor(UIColor.whiteColor(), forState: .Normal) myButton.tag = 100 myButton.bringSubviewToFront(myView) myButton.layerGradient() myView.addSubview(myButton) return myButton } 

我的UIView / UILabel制造商w /文字,阴影和圆angular:

 func myLabelMaker (myView:UIView) -> UIView { let myFrame = CGRectMake(myView.frame.midX / 2 , myView.frame.midY / 2, myView.frame.width/2, myView.frame.height/2) let mylabelFrame = CGRectMake(0, 0, myView.frame.width/2, myView.frame.height/2) let myBaseView = UIView() myBaseView.frame = myFrame myBaseView.backgroundColor = UIColor.clearColor() let myLabel = UILabel() myLabel.backgroundColor=UIColor.pastelYellowColor() myLabel.frame = mylabelFrame myLabel.attributedText = myAttributedText("This is my String",20.0,FontValue.FVLight) myLabel.numberOfLines = 5 myLabel.tag = 100 myLabel.layer.cornerRadius = myLabel.bounds.size.width / MyConstants.CornerRadius.toRaw() myLabel.clipsToBounds = true myLabel.layerborders() myBaseView.addSubview(myLabel) myBaseView.layerShadow() myBaseView.layerGradient() myView.addSubview(myBaseView) return myLabel } 

通用阴影添加:

 func viewshadow<T where T: UIView> (shadowObject: T) { let layer = shadowObject.layer let radius = shadowObject.frame.size.width / MyConstants.CornerRadius.toRaw(); layer.borderColor = UIColor.whiteColor().CGColor layer.borderWidth = 0.8 layer.cornerRadius = radius layer.shadowOpacity = 1 layer.shadowRadius = 3 layer.shadowOffset = CGSizeMake(2.0,2.0) layer.shadowColor = UIColor.shadowColor().CGColor } 

查看扩展视图样式:

 extension UIView { func layerborders() { let layer = self.layer let frame = self.frame let myColor = self.backgroundColor layer.borderColor = myColor.CGColor layer.borderWidth = 10.8 layer.cornerRadius = layer.borderWidth / MyConstants.CornerRadius.toRaw() } func layerShadow() { let layer = self.layer let frame = self.frame layer.cornerRadius = layer.borderWidth / MyConstants.CornerRadius.toRaw() layer.shadowOpacity = 1 layer.shadowRadius = 3 layer.shadowOffset = CGSizeMake(2.0,2.0) layer.shadowColor = UIColor.shadowColor().CGColor } func layerGradient() { let layer = CAGradientLayer() let size = self.frame.size layer.frame.size = size layer.frame.origin = CGPointMake(0.0,0.0) layer.cornerRadius = layer.bounds.size.width / MyConstants.CornerRadius.toRaw(); var color0 = CGColorCreateGenericRGB(250.0/255, 250.0/255, 250.0/255, 0.5) var color1 = CGColorCreateGenericRGB(200.0/255, 200.0/255, 200.0/255, 0.1) var color2 = CGColorCreateGenericRGB(150.0/255, 150.0/255, 150.0/255, 0.1) var color3 = CGColorCreateGenericRGB(100.0/255, 100.0/255, 100.0/255, 0.1) var color4 = CGColorCreateGenericRGB(50.0/255, 50.0/255, 50.0/255, 0.1) var color5 = CGColorCreateGenericRGB(0.0/255, 0.0/255, 0.0/255, 0.1) var color6 = CGColorCreateGenericRGB(150.0/255, 150.0/255, 150.0/255, 0.1) layer.colors = [color0,color1,color2,color3,color4,color5,color6] self.layer.insertSublayer(layer, atIndex: 2) } } 

实际的视图没有加载函数:

 func buttonPress (sender:UIButton!) { NSLog("%@", "ButtonPressed") } override func viewDidLoad() { super.viewDidLoad() let myLabel = myLabelMaker(myView) let myButton = myButtonMaker(myView) myButton.addTarget(self, action: "buttonPress:", forControlEvents:UIControlEvents.TouchUpInside) viewshadow(myButton) viewshadow(myLabel) } 

我认为,使用regular expressions来查找应用属性的范围是一个非常方便的方法。 这是我做到的:

 NSMutableAttributedString *goodText = [[NSMutableAttributedString alloc] initWithString:articleText]; NSRange range = [articleText rangeOfString:@"\\[.+?\\]" options:NSRegularExpressionSearch|NSCaseInsensitiveSearch]; if (range.location != NSNotFound) { [goodText addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Georgia" size:16] range:range]; [goodText addAttribute:NSForegroundColorAttributeName value:[UIColor brownColor] range:range]; } NSString *regEx = [NSString stringWithFormat:@"%@.+?\\s", [self.article.titleText substringToIndex:0]]; range = [articleText rangeOfString:regEx options:NSRegularExpressionSearch|NSCaseInsensitiveSearch]; if (range.location != NSNotFound) { [goodText addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Georgia-Bold" size:20] range:range]; [goodText addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:range]; } [self.textView setAttributedText:goodText]; 

我正在寻找可用属性的列表,并没有在这里和类引用的第一页中find它们。 所以我决定在这里发布信息。

标准属性

已赋值的string支持以下文本的标准属性。 如果密钥不在字典中,则使用下面描述的默认值。

 NSString *NSFontAttributeName; NSString *NSParagraphStyleAttributeName; NSString *NSForegroundColorAttributeName; NSString *NSUnderlineStyleAttributeName; NSString *NSSuperscriptAttributeName; NSString *NSBackgroundColorAttributeName; NSString *NSAttachmentAttributeName; NSString *NSLigatureAttributeName; NSString *NSBaselineOffsetAttributeName; NSString *NSKernAttributeName; NSString *NSLinkAttributeName; NSString *NSStrokeWidthAttributeName; NSString *NSStrokeColorAttributeName; NSString *NSUnderlineColorAttributeName; NSString *NSStrikethroughStyleAttributeName; NSString *NSStrikethroughColorAttributeName; NSString *NSShadowAttributeName; NSString *NSObliquenessAttributeName; NSString *NSExpansionAttributeName; NSString *NSCursorAttributeName; NSString *NSToolTipAttributeName; NSString *NSMarkedClauseSegmentAttributeName; NSString *NSWritingDirectionAttributeName; NSString *NSVerticalGlyphFormAttributeName; NSString *NSTextAlternativesAttributeName; 

NSAttributedString编程指南

完整的类参考在这里 。

这个解决scheme将适用于任何长度

 NSString *strFirst = @"Anylengthtext"; NSString *strSecond = @"Anylengthtext"; NSString *strThird = @"Anylengthtext"; NSString *strComplete = [NSString stringWithFormat:@"%@ %@ %@",strFirst,strSecond,strThird]; NSMutableAttributedString *attributedString =[[NSMutableAttributedString alloc] initWithString:strComplete]; [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:[strComplete rangeOfString:strFirst]]; [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor yellowColor] range:[strComplete rangeOfString:strSecond]]; [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:[strComplete rangeOfString:strThird]]; self.lblName.attributedText = attributedString; 

我写了助手来轻松添加属性:

 - (void)addColor:(UIColor *)color substring:(NSString *)substring; - (void)addBackgroundColor:(UIColor *)color substring:(NSString *)substring; - (void)addUnderlineForSubstring:(NSString *)substring; - (void)addStrikeThrough:(int)thickness substring:(NSString *)substring; - (void)addShadowColor:(UIColor *)color width:(int)width height:(int)height radius:(int)radius substring:(NSString *)substring; - (void)addFontWithName:(NSString *)fontName size:(int)fontSize substring:(NSString *)substring; - (void)addAlignment:(NSTextAlignment)alignment substring:(NSString *)substring; - (void)addColorToRussianText:(UIColor *)color; - (void)addStrokeColor:(UIColor *)color thickness:(int)thickness substring:(NSString *)substring; - (void)addVerticalGlyph:(BOOL)glyph substring:(NSString *)substring; 

https://github.com/shmidt/MASAttributes

你也可以通过CocoaPods安装: pod 'MASAttributes', '~> 1.0.0'

从iOS 7开始,您可以使用带有HTML语法的NSAttributedString

 NSURL *htmlString = [[NSBundle mainBundle] URLForResource: @"string" withExtension:@"html"]; NSAttributedString *stringWithHTMLAttributes = [[NSAttributedString alloc] initWithFileURL:htmlString options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType} documentAttributes:nil error:nil]; textView.attributedText = stringWithHTMLAttributes;// you can use a label also 

您必须将文件“string.html”添加到您的项目,并且html的内容可以是这样的:

 <html> <head> <style type="text/css"> body { font-size: 15px; font-family: Avenir, Arial, sans-serif; } .red { color: red; } .green { color: green; } .blue { color: blue; } </style> </head> <body> <span class="red">first</span><span class="green">second</span><span class="blue">third</span> </body> </html> 

现在,您可以使用NSAttributedString ,即使没有HTML文件,例如:

 //At the top of your .m file #define RED_OCCURENCE -red_occurence- #define GREEN_OCCURENCE -green_occurence- #define BLUE_OCCURENCE -blue_occurence- #define HTML_TEMPLATE @"<span style=\"color:red\">-red_occurence-</span><span style=\"color:green\">-green_occurence-</span><span style=\"color:blue\">-blue_occurence-</span></body></html>" //Where you need to use your attributed string NSString *string = [HTML_TEMPLATE stringByReplacingOccurrencesOfString:RED_OCCURENCE withString:@"first"] ; string = [string stringByReplacingOccurrencesOfString:GREEN_OCCURENCE withString:@"second"]; string = [string stringByReplacingOccurrencesOfString:BLUE_OCCURENCE withString:@"third"]; NSData* cData = [string dataUsingEncoding:NSUTF8StringEncoding]; NSAttributedString *stringWithHTMLAttributes = [[NSAttributedString alloc] initWithData:cData options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType} documentAttributes:nil error:nil]; textView.attributedText = stringWithHTMLAttributes; 

资源

我总是发现使用属性string是一个令人难以置信的漫长而乏味的过程。

所以我做了一个Mac App,为你创build所有的代码。

https://itunes.apple.com/us/app/attributed-string-creator/id730928349?mt=12

你可以像下面一样在Swift加载一个HTML属性string

  var Str = NSAttributedString( data: htmlstring.dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: true), options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil, error: nil) label.attributedText = Str 

从文件加载一个html

  if let rtf = NSBundle.mainBundle().URLForResource("rtfdoc", withExtension: "rtf", subdirectory: nil, localization: nil) { let attributedString = NSAttributedString(fileURL: rtf, options: [NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType], documentAttributes: nil, error: nil) textView.attributedText = attributedString textView.editable = false } 

http://sketchytech.blogspot.in/2013/11/creating-nsattributedstring-from-html.html

并根据您所需的属性设置string….按照此..
http://makeapppie.com/2014/10/20/swift-swift-using-attributed-strings-in-swift/

我做了一个图书馆,这使得这更容易。 看看ZenCopy: https : //github.com/trifl/ZenCopy

您可以创buildStyle对象,并/或将它们设置为键以供稍后参考。 喜欢这个:

 ZenCopy.manager.config.setStyles { return [ "token": Style( color: .blueColor(), // optional // fontName: "Helvetica", // optional fontSize: 14 // optional ) ] } 

然后,你可以很容易地构造string和样式他们,并有params 🙂

 label.attributedText = attributedString( ["$0 ".style("token") "is dancing with ", "$1".style("token")], args: ["JP", "Brock"] ) 

你也可以使用正则expression式来轻松地设置样式

 let atUserRegex = "(@[A-Za-z0-9_]*)" mutableAttributedString.regexFind(atUserRegex, addStyle: "token") 

这将使用“标记”风格对所有带有“@”的单词进行设置。 (如@jpmcglone)

我仍然需要NSAttributedString所提供的一切工作,但我认为fontName,fontSize和color覆盖了它的大部分。 期待很多更新很快:)

如果您需要,我可以帮助您开始使用。 也寻找反馈,所以如果它让你的生活更轻松,我会说任务完成。

 - (void)changeColorWithString:(UILabel *)uilabel stringToReplace:(NSString *) stringToReplace uiColor:(UIColor *) uiColor{ NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithAttributedString: uilabel.attributedText]; [text addAttribute: NSForegroundColorAttributeName value:uiColor range:[uilabel.text rangeOfString:stringToReplace]]; [uilabel setAttributedText: text]; } 

在Swift 4:

 let string:NSMutableAttributedString = { let mutableString = NSMutableAttributedString(string: "firstsecondthird") mutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.red , range: NSRange(location: 0, length: 5)) mutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.green , range: NSRange(location: 5, length: 6)) mutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.blue , range: NSRange(location: 11, length: 5)) return mutableString }() print(string) 

为了解决这样一个问题,我创build了一个名为Atributika的快速库。

 let str = "<r>first</r><g>second</g><b>third</b>".style(tags: Style("r").foregroundColor(.red), Style("g").foregroundColor(.green), Style("b").foregroundColor(.blue)).attributedString label.attributedText = str 

你可以在这里findhttps://github.com/psharanda/Atributika

属性string扩展的更简单解决scheme。

 extension NSMutableAttributedString { // this function attaches color to string func setColorForText(textToFind: String, withColor color: UIColor) { let range: NSRange = self.mutableString.range(of: textToFind, options: .caseInsensitive) self.addAttribute(NSAttributedStringKey.foregroundColor, value: color, range: range) } } 

试试看看(Swift 3&4testing)

 let label = UILabel() label.frame = CGRect(x: 120, y: 100, width: 200, height: 30) let first = "first" let second = "second" let third = "third" let stringValue = "\(first)\(second)\(third)" // or direct assign single string value like "firstsecondthird" let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: stringValue) attributedString.setColorForText(textToFind: first, withColor: UIColor.red) // use variable for string "first" attributedString.setColorForText(textToFind: "second", withColor: UIColor.green) // or direct string like this "second" attributedString.setColorForText(textToFind: third, withColor: UIColor.blue) label.font = UIFont.systemFont(ofSize: 26) label.attributedText = attributedString self.view.addSubview(label) 

预计结果如下:

在这里输入图像描述