เปลี่ยนสีสตริงด้วย NSAttributedString?


147

ฉันมีตัวเลื่อนสำหรับแบบสำรวจที่แสดงสตริงต่อไปนี้โดยยึดตามค่าของตัวเลื่อน: "แย่มากแย่ไม่ดีดีมาก"

นี่คือรหัสสำหรับตัวเลื่อน:

- (IBAction) sliderValueChanged:(UISlider *)sender {
    scanLabel.text = [NSString stringWithFormat:@" %.f", [sender value]];
    NSArray *texts=[NSArray arrayWithObjects:@"Very Bad", @"Bad", @"Okay", @"Good", @"Very Good", @"Very Good", nil];
    NSInteger sliderValue=[sender value]; //make the slider value in given range integer one.
    self.scanLabel.text=[texts objectAtIndex:sliderValue];
}

ฉันต้องการให้ "แย่มาก" เป็นสีแดง "แย่" เป็นสีส้ม "โอเค" เป็นสีเหลือง "ดี" และ "ดีมาก" เป็นสีเขียว

ฉันไม่เข้าใจวิธีใช้NSAttributedStringในการทำสิ่งนี้ให้สำเร็จ



คุณหมายถึง UISlider ใช่ไหม ไม่ได้มีฉลาก ดังนั้นโดยพื้นฐานแล้วมันเกี่ยวกับ UILabel ที่มีสีตัวอักษร? หรือคุณต้องการส่วนหนึ่งของสีข้อความ?
Roger

2
ความเป็นไปได้ที่ซ้ำกันของNSAttributedString คุณใช้งานอย่างไร
John Parker

ใช้ห้องสมุดนี้มันง่ายเล็กน้อย github.com/iOSTechHub/AttributedString
Ashish Chauhan

คำตอบ:


196

NSAttributedStringไม่จำเป็นต้องมีการใช้ไม่เป็น textColorทั้งหมดที่คุณต้องมีฉลากง่ายด้วยที่เหมาะสม นอกจากนี้โซลูชันที่ง่ายนี้จะทำงานกับ iOS ทุกรุ่นไม่ใช่เฉพาะ iOS 6

แต่ถ้าคุณต้องการใช้โดยไม่จำเป็นNSAttributedStringคุณสามารถทำสิ่งนี้:

UIColor *color = [UIColor redColor]; // select needed color
NSString *string = ... // the string to colorize
NSDictionary *attrs = @{ NSForegroundColorAttributeName : color };
NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:string attributes:attrs];
self.scanLabel.attributedText = attrStr;

4
ฉันไม่เข้าใจการลงคะแนนเสียงทั้งหมด คำตอบของฉันง่ายกว่าการใช้สตริงประกอบ OP ไม่จำเป็นต้องใช้NSAttributedStringสำหรับงานนี้ มันจะเป็นสิ่งหนึ่งถ้าข้อความของป้ายกำกับต้องการแอตทริบิวต์หลายรายการ แต่ไม่ต้องการ ฉลากทั้งหมดต้องเป็นหนึ่งสีในแต่ละครั้ง
rmaddy

@ RubénE.Marín แต่นั่นเป็นปัญหา NSAttributedStringสหกรณ์หลงผิดคิดว่าการแก้ปัญหาที่จำเป็นต้องใช้ นั่นคือสิ่งที่พวกเขาขอ คำถามที่แท้จริงควรจะได้รับ"วิธีการตั้งค่าสีของฉลากบนพื้นฐานของความคุ้มค่า" ฉันชี้ให้เห็นว่าวิธีแก้ปัญหาไม่ต้องการNSAttributedStringและแสดงคำตอบที่ง่ายกว่านี้มาก และ OP เห็นด้วยโดยยอมรับคำตอบที่ง่ายกว่าของฉัน หากต้องการOP จริง ๆNSAttributedStringพวกเขาจะไม่ยอมรับคำตอบของฉัน ดังนั้นจึงไม่มีเหตุผลในการลงคะแนนเสียง ฉันตอบคำถามจริงและยอมรับ OP
rmaddy

24
ในกรณีนั้นฉันจะแก้ไขคำถามด้วย NSAttributedString และหลังจากนั้นฉันจะชี้ให้เห็นวิธีที่ง่ายและมีประสิทธิภาพมากขึ้นสำหรับกรณีเฉพาะของ OP คนที่มาที่คำถามนี้อาจรู้สึกหงุดหงิดกับวิธีการแก้ปัญหาของคุณเพราะพวกเขากำลังมองหาวิธีเปลี่ยนสีข้อความบน NSAttributedString (และนั่นจะอธิบายการลงคะแนนเสียงของคุณ)
Ruben Marin

15
Rubénพูดถูก: ฉันมาที่นี่เพราะฉันต้องการตั้งค่าสีเป็นสตริงที่มีการระบุเพราะฉันกำลังสร้างสตริงที่ประกอบขึ้นด้วยหลายสีและขนาดแบบอักษร และข้อมูลสำคัญที่ฉันต้องการก็คือNSForegroundColorAttributeNameกุญแจซึ่งฉันมีปัญหาในการค้นหาเอกสาร Apple
Erik van der Neut

5
ขอบคุณที่ยังคงตอบคำถาม !! แม้ว่า OP ไม่ต้องการจริงๆ หลายครั้งที่ฉันทำอะไรบางอย่างใน google จบลงด้วยคำถามล้นสแต็คนั่นคือสิ่งที่ฉันกำลังมองหาเท่านั้นที่จะพบว่าคนฉลาดตอบคำถามตัดสินใจว่า OP ไม่ต้องการสิ่งที่ชื่อคำถามถาม ตอบคำถามที่แตกต่างอย่างสิ้นเชิง ผู้คนในอนาคตที่มาจากผลการค้นหาซึ่งอาจมี 1,000 รายการเมื่อเทียบกับ 1 OP อาจต้องการทางออกสำหรับคำถามที่ถามในชื่อโพสต์ </rant>
แดนนี

112

ใช้สิ่งนี้ (ไม่คอมไพเลอร์ที่เลือก)

NSMutableAttributedString *string = [[NSMutableAttributedString alloc]initWithString:self.text.text];
NSRange range=[self.myLabel.text rangeOfString:texts[sliderValue]]; //myLabel is the outlet from where you will get the text, it can be same or different

NSArray *colors=@[[UIColor redColor],
                  [UIColor redColor],
                  [UIColor yellowColor],
                  [UIColor greenColor]
                 ];

[string addAttribute:NSForegroundColorAttributeName 
               value:colors[sliderValue] 
               range:range];           

[self.scanLabel setAttributedText:texts[sliderValue]];

เฮ้ Anoop ดีใจที่ได้พบคุณอีกครั้ง! ฉันให้รหัสที่คุณให้ไว้ฉันเปลี่ยน self.text.text เป็น self.scanLabel.text แต่ฉันพบข้อผิดพลาดที่ "word" ฉันลองแทนที่ด้วย @ "แย่มาก" โดยไม่มีโชค
อดัม

ฉันคัดลอกคำตอบจากที่นี่stackoverflow.com/questions/14231879/…
Anoop Vaidya

ขอบคุณ Anoop แต่ไม่มีโชคสำหรับฉัน - [__ NSCFString _ui_synthesizeAttributedSubstringFromRange: usingDefaultAttributesA]:: ตัวเลือกที่ไม่ได้รับการบันทึก ': [ตัวเลือกที่ไม่รู้จัก]' _ui_synthesizeAttributedSubstringFromRange: usingDefaultAttributes:]: ตัวเลือกที่ไม่รู้จักถูกส่งไปยังอินสแตนซ์ 0x1f845af0 '
อดัม

เพียงลองรูปโอทูว่า "ตำรา"
Morkrom

@Morkrom: ถ้าคุณเห็นความคิดเห็นที่ 2 ในคำตอบนี้คุณจะได้รับรู้: p
Anoop Vaidya

48

ในสวิฟต์ 4 :

// Custom color
let greenColor = UIColor(red: 10/255, green: 190/255, blue: 50/255, alpha: 1)
// create the attributed colour
let attributedStringColor = [NSAttributedStringKey.foregroundColor : greenColor];
// create the attributed string
let attributedString = NSAttributedString(string: "Hello World!", attributes: attributedStringColor)
// Set the label
label.attributedText = attributedString

ในสวิฟต์ 3 :

// Custom color
let greenColor = UIColor(red: 10/255, green: 190/255, blue: 50/255, alpha: 1)
// create the attributed color
let attributedStringColor : NSDictionary = [NSForegroundColorAttributeName : greenColor];
// create the attributed string
let attributedString = NSAttributedString(string: "Hello World!", attributes: attributedStringColor as? [String : AnyObject])
// Set the label
label.attributedText = attributedString 

สนุก.


28

สำหรับSwift 5:

var attributes = [NSAttributedString.Key: AnyObject]()
attributes[.foregroundColor] = UIColor.red

let attributedString = NSAttributedString(string: "Very Bad", attributes: attributes)

label.attributedText = attributedString

สำหรับSwift 4:

var attributes = [NSAttributedStringKey: AnyObject]()
attributes[.foregroundColor] = UIColor.red

let attributedString = NSAttributedString(string: "Very Bad", attributes: attributes)

label.attributedText = attributedString

สำหรับSwift 3:

var attributes = [String: AnyObject]()
attributes[NSForegroundColorAttributeName] = UIColor.red

let attributedString = NSAttributedString(string: "Very Bad", attributes: attributes)

label.attributedText = attributedString

7

คุณสามารถสร้าง NSAttributedString

NSDictionary *attributes = @{ NSForegroundColorAttributeName : [UIColor redColor] };
NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:@"My Color String" attributes:attrs];

หรือNSMutableAttributedStringเพื่อใช้คุณสมบัติที่กำหนดเองด้วยช่วง

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@%@", methodPrefix, method] attributes: @{ NSFontAttributeName : FONT_MYRIADPRO(48) }];
[attributedString addAttribute:NSFontAttributeName value:FONT_MYRIADPRO_SEMIBOLD(48) range:NSMakeRange(methodPrefix.length, method.length)];

คุณสมบัติที่มี: NSAttributedStringKey


UPDATE:

สวิฟต์ 5.1

let message: String = greeting + someMessage
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 2.0
    
// Note: UIFont(appFontFamily:ofSize:) is extended init.
let regularAttributes: [NSAttributedString.Key : Any] = [.font : UIFont(appFontFamily: .regular, ofSize: 15)!, .paragraphStyle : paragraphStyle]
let boldAttributes = [NSAttributedString.Key.font : UIFont(appFontFamily: .semiBold, ofSize: 15)!]

let mutableString = NSMutableAttributedString(string: message, attributes: regularAttributes)
mutableString.addAttributes(boldAttributes, range: NSMakeRange(0, greeting.count))

5

กับสวิฟท์ 4 มีคุณสมบัติคงที่เรียกว่าNSAttributedStringKey มีการประกาศดังต่อไปนี้:foregroundColorforegroundColor

static let foregroundColor: NSAttributedStringKey

ค่าของคุณลักษณะนี้เป็นUIColorวัตถุ ใช้แอททริบิวนี้เพื่อระบุสีของข้อความระหว่างการเรนเดอร์ หากคุณไม่ได้ระบุแอททริบิวนี้ข้อความจะแสดงเป็นสีดำ

รหัสสนามเด็กเล่นต่อไปนี้แสดงวิธีตั้งค่าสีข้อความของNSAttributedStringอินสแตนซ์ด้วยforegroundColor:

import UIKit

let string = "Some text"
let attributes = [NSAttributedStringKey.foregroundColor : UIColor.red]
let attributedString = NSAttributedString(string: string, attributes: attributes)

รหัสด้านล่างแสดงการUIViewControllerใช้งานที่เป็นไปได้ที่ต้องอาศัยNSAttributedStringเพื่ออัปเดตข้อความและสีข้อความของ a UILabelจากUISlider:

import UIKit

enum Status: Int {
    case veryBad = 0, bad, okay, good, veryGood

    var display: (text: String, color: UIColor) {
        switch self {
        case .veryBad:  return ("Very bad", .red)
        case .bad:      return ("Bad", .orange)
        case .okay:     return ("Okay", .yellow)
        case .good:     return ("Good", .green)
        case .veryGood: return ("Very good", .blue)
        }
    }

    static let minimumValue = Status.veryBad.rawValue
    static let maximumValue = Status.veryGood.rawValue
}
final class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var slider: UISlider!
    var currentStatus: Status = Status.veryBad {
        didSet {
            // currentStatus is our model. Observe its changes to update our display
            updateDisplay()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Prepare slider
        slider.minimumValue = Float(Status.minimumValue)
        slider.maximumValue = Float(Status.maximumValue)

        // Set display
        updateDisplay()
    }

    func updateDisplay() {
        let attributes = [NSAttributedStringKey.foregroundColor : currentStatus.display.color]
        let attributedString = NSAttributedString(string: currentStatus.display.text, attributes: attributes)
        label.attributedText = attributedString
        slider.value = Float(currentStatus.rawValue)
    }

    @IBAction func updateCurrentStatus(_ sender: UISlider) {
        let value = Int(sender.value.rounded())
        guard let status = Status(rawValue: value) else { fatalError("Could not get Status object from value") }
        currentStatus = status
    }

}

แต่ทราบว่าคุณไม่ได้จริงๆต้องใช้NSAttributedStringตัวอย่างเช่นและก็สามารถพึ่งพาUILabel's textและtextColorคุณสมบัติ ดังนั้นคุณสามารถแทนที่updateDisplay()การใช้งานของคุณด้วยรหัสต่อไปนี้:

func updateDisplay() {
    label.text = currentStatus.display.text
    label.textColor = currentStatus.display.color
    slider.value = Float(currentStatus.rawValue)
}

2

อัปเดตสำหรับ Swift 4.2

var attributes = [NSAttributedString.Key: AnyObject]()

attributes[.foregroundColor] = UIColor.blue

let attributedString = NSAttributedString(string: "Very Bad",
attributes: attributes)

label.attributedText = attributedString

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.