在NSString或nsmutablestring中不可能有多种颜色。我听说过一点NSAttributedString,它是在iPad SDK 3.2(或大约3.2)中引入的,并且在iPhone SDK 4.0 beta版中可用。

我想要一根有三种颜色的绳子。

我不使用3个独立的NSString的原因,是因为三个NSAttributedString子字符串的长度经常改变,所以我宁愿,不使用任何计算重新定位3个独立的NSString对象。

如果使用NSAttributedString是可能的,我怎么做以下-(如果不可能使用NSAttributedString,你会怎么做):

编辑: 记住,@"first", @"second"和@"third"随时会被其他字符串替换。所以使用硬编码的NSRange值是行不通的。


当前回答

这个解对任何长度都适用

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;

其他回答

在构建带属性字符串时,我更喜欢使用可变子类,只是为了让事情更简洁。

话虽如此,下面是如何创建一个三色带属性字符串:

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

带属性字符串扩展的更简单的解决方案。

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和4中测试)

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)

以下是预期结果:

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

所以我做了一个Mac应用程序,为你创建所有的代码。

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

为了解决这类问题,我在swift中创建了一个名为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

你可以在这里找到它https://github.com/psharanda/Atributika

问题已经有了答案……但是我想展示如何用NSAttributedString添加阴影和改变字体,这样当人们搜索这个主题时,他们就不用一直找了。

#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版本…

警告! 这适用于4s。

5s你必须改变所有的Float值为Double值(因为编译器还没有正确工作)

字体选择的Swift枚举:

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

用于enum访问的Swift数组(因为enum不能使用'-'):

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属性文本函数:

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
}

第一个和最后一个扩展名用于查找字符串数组中的范围:

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

我的宏替换:

enum MyConstants: Float {
    case CornerRadius = 5.0
}

我的按钮制造商w/带属性的文本:

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 maker w/带属性的文本,阴影和圆角:

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

实际视图didload函数:

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)

}