Thay đổi màu chuỗi với NSAttributionString?


147

Tôi có một thanh trượt cho một khảo sát hiển thị các chuỗi sau dựa trên giá trị của thanh trượt: "Rất tệ, Xấu, Được, Tốt, Rất tốt".

Đây là mã cho thanh trượt:

- (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];
}

Tôi muốn "Rất tệ" có màu đỏ, "Xấu" có màu cam, "Được" có màu vàng, "Tốt" và "Rất tốt" có màu xanh lá cây.

Tôi không hiểu làm thế nào để sử dụng NSAttributedStringđể thực hiện điều này.



Bạn có nghĩa là một UISlider? Điều đó không có nhãn. Vì vậy, về cơ bản nó là về một UILabel với một màu phông chữ? Hay bạn muốn một phần của văn bản màu?
Roger


Sử dụng thư viện này, nó rất đơn giản. github.com/iOSTechHub/AttributionString
Ashish Chauhan

Câu trả lời:


196

Không có nhu cầu sử dụng NSAttributedString. Tất cả bạn cần là một nhãn đơn giản với thích hợp textColor. Thêm vào đó, giải pháp đơn giản này sẽ hoạt động với tất cả các phiên bản iOS, không chỉ iOS 6.

Nhưng nếu bạn không muốn sử dụng NSAttributedString, bạn có thể làm một cái gì đó như thế này:

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
Tôi không hiểu tất cả các phiếu bầu. Câu trả lời của tôi đơn giản hơn nhiều so với việc sử dụng một chuỗi được quy. OP không có nhu cầu sử dụng NSAttributedStringcho nhiệm vụ này. Sẽ là một điều nếu văn bản của nhãn cần nhiều thuộc tính nhưng không. Toàn bộ nhãn cần phải là một màu tại một thời điểm.
rmaddy

@ RubénE.Marín Nhưng đó là vấn đề. OP nhầm tưởng rằng giải pháp cần sử dụng NSAttributedString. Vì vậy, đó là những gì họ yêu cầu. Câu hỏi thực sự phải là "Cách đặt màu của nhãn dựa trên giá trị của nó" . Tôi chỉ ra rằng giải pháp không yêu cầu NSAttributedStringvà cho thấy một câu trả lời đơn giản hơn nhiều. Và OP đã đồng ý bằng cách chấp nhận câu trả lời đơn giản hơn nhiều của tôi. Nếu OP thực sự muốn NSAttributedString, họ sẽ không chấp nhận câu trả lời của tôi. Vì vậy, không có lý do cho các phiếu giảm. Tôi đã trả lời câu hỏi thực sự và OP chấp nhận.
rmaddy 11/03/2015

24
Trong trường hợp đó, tôi đã giải quyết câu hỏi với NSAttributionString và sau đó, tôi sẽ chỉ ra giải pháp đơn giản và hiệu quả hơn của bạn cho trường hợp cụ thể của OP. Những người đến với câu hỏi này có thể cảm thấy thất vọng bởi giải pháp của bạn vì họ đang tìm cách thay đổi màu văn bản trên NSAttributionString (và điều đó sẽ giải thích cho phiếu bầu của bạn).
Ruben Marin

15
Rubén đã đúng: Tôi đến đây vì tôi cần phải đặt màu trong một chuỗi được gán, bởi vì tôi đang xây dựng một chuỗi được gán ghép với nhiều màu và kích cỡ phông chữ. Và thông tin chính tôi cần là NSForegroundColorAttributeNamechìa khóa, thứ mà tôi đã có một thời gian khó tìm thấy trong các tài liệu của Apple.
Erik van der Neut 13/05/2015

5
Cảm ơn bạn vẫn trả lời câu hỏi !! ngay cả khi OP không thực sự cần nó. Vì vậy, nhiều lần tôi google một cái gì đó, kết thúc với một câu hỏi tràn chồng chính xác là những gì tôi đang tìm kiếm, chỉ để thấy rằng người khôn ngoan trả lời câu hỏi đã quyết định OP không thực sự cần tiêu đề câu hỏi nào và đã trả lời một câu hỏi hoàn toàn khác Chà, mọi người trong tương lai đến từ kết quả tìm kiếm, trong đó có thể có 1000 điểm trái ngược với 1 OP, thực sự có thể muốn có một giải pháp cho câu hỏi được đặt ra trong tiêu đề của bài đăng. </ rant>
danny

112

Sử dụng một cái gì đó như thế này (Không kiểm tra trình biên dịch)

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]];

Này Anoop, rất vui khi gặp lại bạn! Tôi đã mã hóa mã bạn cung cấp, tôi đã thay thế self.text.text bằng self.scanLabel.text, nhưng tôi đang gặp lỗi tại "word". Tôi đã thử thay thế nó bằng @ "Rất tệ" nhưng không có may mắn.
Adam

Tôi đã sao chép câu trả lời của mình từ đây stackoverflow.com/questions/14231879/ từ
Anoop Vaidya

Cảm ơn Anoop, nhưng không có may mắn cho tôi. - [[N_FSClString _ui_synthesizeAttributionSubopesFromRange: usingDefaultAttribut:]: bộ chọn không được nhận dạng được gửi đến ví dụ 0x1f845af0 '
Adam

Chỉ cần cố gắng để tìm otu những "văn bản"
Morkrom

@Morkrom: nếu bạn thấy bình luận thứ 2 trong câu trả lời này, thì bạn sẽ biết: p
Anoop Vaidya

48

Trong Swift 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

Trong Swift 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 

Thưởng thức.


28

Dành cho Swift 5:

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

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

label.attributedText = attributedString

Dành cho Swift 4:

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

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

label.attributedText = attributedString

Dành cho Swift 3:

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

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

label.attributedText = attributedString

7

Bạn có thể tạo NSAttributedString

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

HOẶC NSMutableAttributedStringđể áp dụng các thuộc tính tùy chỉnh với Phạm vi.

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)];

Thuộc tính có sẵn: NSAttributionStringKey


CẬP NHẬT:

Swift 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

Với Swift 4, NSAttributedStringKeycó một thuộc tính tĩnh được gọi foregroundColor. foregroundColorcó tuyên bố sau:

static let foregroundColor: NSAttributedStringKey

Giá trị của thuộc tính này là một UIColorđối tượng. Sử dụng thuộc tính này để chỉ định màu của văn bản trong khi kết xuất. Nếu bạn không chỉ định thuộc tính này, văn bản được hiển thị màu đen.

Mã Playground sau đây cho biết cách đặt màu văn bản của một NSAttributedStringthể hiện với foregroundColor:

import UIKit

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

Mã dưới đây cho thấy một UIViewControllertriển khai có thể dựa vào NSAttributedStringđể cập nhật văn bản và màu văn bản của một UILabeltừ 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
    }

}

Tuy nhiên, lưu ý rằng bạn không thực sự cần sử dụng NSAttributedStringcho một ví dụ như vậy và chỉ có thể dựa vào UILabelcác thuộc tính texttextColor. Do đó, bạn có thể thay thế updateDisplay()triển khai của mình bằng mã sau:

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

2

Cập nhật cho Swift 4.2

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

attributes[.foregroundColor] = UIColor.blue

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

label.attributedText = attributedString

1

Một lớp lót cho Swift:

NSAttributedString(string: "Red Text", attributes: [.foregroundColor: UIColor.red])
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.