Ubah warna string dengan NSAttributedString?

147

Saya memiliki slider untuk survei yang menampilkan string berikut berdasarkan nilai slider: "Sangat Buruk, Buruk, Oke, Bagus, Sangat Bagus".

Berikut adalah kode untuk slider:

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

Saya ingin "Sangat Buruk" menjadi merah, "Buruk" menjadi oranye, "Oke" menjadi kuning, "Baik" dan "Sangat Bagus" menjadi hijau.

Saya tidak mengerti bagaimana menggunakannya NSAttributedStringuntuk menyelesaikan ini.

Adam
sumber
ini
Maksud Anda seorang UISlider? Itu tidak memiliki label. Jadi pada dasarnya ini tentang UILabel dengan warna font? Atau Anda ingin bagian teks berwarna?
Roger
2
kemungkinan duplikat dari Bagaimana Anda menggunakan NSAttributedString?
John Parker
Gunakan perpustakaan ini, sangat sederhana. github.com/iOSTechHub/AttributedString
Ashish Chauhan

Jawaban:

196

Tidak perlu menggunakan NSAttributedString. Yang Anda butuhkan hanyalah label sederhana dengan yang tepat textColor. Plus solusi sederhana ini akan bekerja dengan semua versi iOS, bukan hanya iOS 6.

Tetapi jika Anda ingin menggunakannya secara tidak perlu NSAttributedString, Anda dapat melakukan sesuatu seperti ini:

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;
rmaddy
sumber
4
Saya tidak mengerti semua suara turun. Jawaban saya jauh lebih sederhana daripada menggunakan string yang dikaitkan. OP tidak perlu menggunakan NSAttributedStringuntuk tugas ini. Ini akan menjadi satu hal jika teks label membutuhkan banyak atribut tetapi tidak. Seluruh label harus satu warna pada satu waktu.
rmaddy
@ RubénE.Marín Tapi itu masalahnya. OP keliru mengira bahwa solusi diperlukan menggunakan NSAttributedString. Jadi itu yang mereka minta. Pertanyaan sebenarnya seharusnya adalah "Bagaimana mengatur warna label berdasarkan nilainya" . Saya menunjukkan bahwa solusi tidak memerlukan NSAttributedStringdan menunjukkan jawaban yang jauh lebih sederhana. Dan OP setuju dengan menerima jawaban saya yang jauh lebih sederhana. Jika OP benar - benar ingin NSAttributedString, mereka tidak akan menerima jawaban saya. Jadi tidak ada alasan untuk suara turun. Saya menjawab pertanyaan yang sebenarnya dan OP menerima.
rmaddy
24
Dalam hal ini, saya akan menyelesaikan pertanyaan dengan NSAttributedString dan, setelah itu, saya akan menunjukkan solusi Anda yang lebih sederhana dan lebih efisien untuk kasus OP tertentu. Orang yang datang ke pertanyaan ini mungkin merasa frustrasi dengan solusi Anda karena mereka mencari cara untuk mengubah warna teks pada NSAttributedString (dan itu akan menjelaskan suara Anda).
Ruben Marin
15
Rubén benar: Saya datang ke sini karena saya perlu mengatur warna dalam string yang dikaitkan, karena saya sedang membangun string yang dikaitkan dengan beberapa warna dan ukuran font. Dan informasi kunci yang saya butuhkan adalah NSForegroundColorAttributeNamekunci, yang sulit saya temukan di dokumen Apple.
Erik van der Neut
5
Terima kasih karena masih menjawab pertanyaan !! bahkan jika OP tidak benar-benar membutuhkannya. Berkali-kali saya mencari sesuatu di Google, berakhir dengan pertanyaan tumpukan yang melimpah itulah yang saya cari, hanya untuk menemukan bahwa orang bijak yang menjawab pertanyaan itu memutuskan OP tidak benar-benar membutuhkan apa yang diminta judul pertanyaan dan menjawab pertanyaan yang sama sekali berbeda. Nah, orang-orang di masa depan yang berasal dari hasil pencarian, yang mungkin ada 1000's sebagai lawan dari 1 OP, mungkin benar-benar menginginkan solusi untuk pertanyaan yang diajukan dalam judul posting. </rant>
danny
112

Gunakan sesuatu seperti ini (Tidak diperiksa kompilator)

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 Vaidya
sumber
Hei Anoop, senang bertemu denganmu lagi! Saya memeriksa kode yang Anda berikan, saya mengganti self.text.text dengan self.scanLabel.text, tetapi saya mendapatkan kesalahan pada "kata". Saya mencoba menggantinya dengan @ "Sangat Buruk" tanpa hasil.
Adam
Saya menyalin jawaban saya dari sini stackoverflow.com/questions/14231879/…
Anoop Vaidya
Terima kasih Anoop, tetapi tidak berhasil bagi saya. - [__ NSCFString _ui_synthesizeAttributedSubstringFromRange: usingDefaultAttributes:]: pemilih yang tidak dikenal dikirim ke instance 0x1f845af0 2013-01-11 16: 27: 34.939 yellaProto [7829: 907] *** Mengakhiri aplikasi karena alasan tidak wajar, kecuali NSR, kecuali karena alasan yang wajar: _ui_synthesizeAttributedSubstringFromRange: usingDefaultAttributes:]: pemilih yang tidak dikenal dikirim ke instance 0x1f845af0 '
Adam
Coba cari tahu "teks" apa
Morkrom
@Morkrom: jika Anda melihat komentar ke-2 dalam jawaban ini, maka Anda akan mengetahui: p
Anoop Vaidya
48

Dalam 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

Dalam 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 

Nikmati.

App Dev Guy
sumber
28

Untuk Swift 5:

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

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

label.attributedText = attributedString

Untuk Swift 4:

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

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

label.attributedText = attributedString

Untuk Swift 3:

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

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

label.attributedText = attributedString
pableiros
sumber
7

Anda bisa membuat NSAttributedString

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

ATAU NSMutableAttributedStringuntuk menerapkan atribut khusus dengan Ranges.

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

Atribut yang Tersedia: NSAttributedStringKey


MEMPERBARUI:

Cepat 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))
Lal Krishna
sumber
5

Dengan Swift 4, NSAttributedStringKeymemiliki properti statis yang disebut foregroundColor. foregroundColormemiliki deklarasi berikut:

static let foregroundColor: NSAttributedStringKey

Nilai dari atribut ini adalah sebuah UIColorobjek. Gunakan atribut ini untuk menentukan warna teks selama rendering. Jika Anda tidak menentukan atribut ini, teks diterjemahkan dalam warna hitam.

Kode Playground berikut menunjukkan cara mengatur warna teks NSAttributedStringinstance dengan foregroundColor:

import UIKit

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

Kode di bawah ini menunjukkan kemungkinan UIViewControllerimplementasi yang bergantung pada NSAttributedStringuntuk memperbarui teks dan warna teks UILabeldari 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
    }

}

Namun perlu dicatat bahwa Anda tidak benar-benar perlu menggunakan NSAttributedStringmisalnya seperti itu dan hanya bisa mengandalkan UILabel's textdan textColorsifat. Oleh karena itu, Anda dapat mengganti updateDisplay()implementasi Anda dengan kode berikut:

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

Pembaruan untuk Swift 4.2

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

attributes[.foregroundColor] = UIColor.blue

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

label.attributedText = attributedString
Mithra Singam
sumber
1

Satu liner untuk Swift:

NSAttributedString(string: "Red Text", attributes: [.foregroundColor: UIColor.red])
Fedotchenco Denis
sumber