Mengubah warna teks tertentu menggunakan NSMutableAttributedString di Swift

100

Masalah yang saya alami adalah saya ingin dapat mengubah textColor dari teks tertentu dalam TextView. Saya menggunakan string gabungan, dan hanya ingin string yang saya tambahkan ke teks TextView. Tampaknya yang ingin saya gunakan adalah NSMutableAttributedString, tetapi saya tidak menemukan sumber daya apa pun tentang cara menggunakan ini di Swift. Apa yang saya miliki sejauh ini adalah seperti ini:

let string = "A \(stringOne) with \(stringTwo)"
var attributedString = NSMutableAttributedString(string: string)
textView.attributedText = attributedString

Dari sini saya tahu saya perlu menemukan rentang kata yang perlu diubah textColornya dan kemudian menambahkannya ke string yang dikaitkan. Yang perlu saya ketahui adalah bagaimana menemukan string yang benar dari atributedString, dan kemudian mengubah textColornya.

Karena saya memiliki peringkat yang terlalu rendah, saya tidak dapat menjawab pertanyaan saya sendiri, tetapi inilah jawaban yang saya temukan

Saya menemukan jawaban saya sendiri dengan menerjemahkan dari menerjemahkan beberapa kode dari

Ubah atribut substring di NSAttributedString

Berikut adalah contoh implementasi di Swift:

let string = "A \(stringOne) and \(stringTwo)"
var attributedString = NSMutableAttributedString(string:string)

let stringOneRegex = NSRegularExpression(pattern: nameString, options: nil, error: nil)
let stringOneMatches = stringOneRegex.matchesInString(longString, options: nil, range: NSMakeRange(0, attributedString.length))
for stringOneMatch in stringOneMatches {
    let wordRange = stringOneMatch.rangeAtIndex(0)
    attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.nameColor(), range: wordRange)
}

textView.attributedText = attributedString

Karena saya ingin mengubah textColor dari beberapa Strings, saya akan membuat fungsi pembantu untuk menangani ini, tetapi ini berfungsi untuk mengubah textColor.

richyrich24
sumber
Apakah Anda tahu cara melakukannya di Objective-C? Sudahkah Anda mencoba menulis ulang kode yang sama di Swift?
Aaron Brager
Berikut adalah jawaban yang sangat bagus: stackoverflow.com/a/37992022/426571
el_quick

Jawaban:

110

Saya melihat Anda agak menjawab pertanyaan itu, tetapi untuk memberikan cara yang sedikit lebih ringkas tanpa menggunakan regex untuk menjawab pertanyaan judul:

Untuk mengubah warna panjang teks Anda perlu mengetahui indeks awal dan akhir dari karakter yang akan diwarnai dalam string misalnya

var main_string = "Hello World"
var string_to_color = "World"

var range = (main_string as NSString).rangeOfString(string_to_color)

Kemudian Anda mengonversi ke string yang diatribusikan dan menggunakan 'tambahkan atribut' dengan NSForegroundColorAttributeName:

var attributedString = NSMutableAttributedString(string:main_string)
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor() , range: range)

Daftar atribut standar lebih lanjut yang dapat Anda atur dapat ditemukan di dokumentasi Apple

james_alvarez
sumber
20
NSColor hanya untuk OSX - gunakan UIColor untuk IOS
Steve O'Connor
1
Bagaimana jika saya memiliki var main_string = "Hello World Hello World Hello World" dan saya perlu menerapkan warna pada "World" di seluruh string?
msmq
main_string, string_to_colordan rangetidak pernah bermutasi. Pertimbangkan untuk mengubahnya menjadi letkonstan?
Cesare
Solusi bagus. Anda telah menyelamatkan hari saya.
Sagar Chauhan
106

SWIFT 5

let main_string = "Hello World"
let string_to_color = "World"

let range = (main_string as NSString).range(of: string_to_color)

let attribute = NSMutableAttributedString.init(string: main_string)
attribute.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red , range: range)


txtfield1 = UITextField.init(frame:CGRect(x:10 , y:20 ,width:100 , height:100))
txtfield1.attributedText = attribute

SWIFT 4.2

 let txtfield1 :UITextField!

    let main_string = "Hello World"
    let string_to_color = "World"

    let range = (main_string as NSString).range(of: string_to_color)

    let attribute = NSMutableAttributedString.init(string: main_string)
    attribute.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.red , range: range)


    txtfield1 = UITextField.init(frame:CGRect(x:10 , y:20 ,width:100 , height:100))
    txtfield1.attributedText = attribute
Kishore Kumar
sumber
bagaimana jika stringnya besar, dan memiliki banyak duplikasi kata (serupa). Akankah range (dari: ...) bekerja?
Hatim
44

Pembaruan Swift 2.1:

 let text = "We tried to make this app as most intuitive as possible for you. If you have any questions don't hesitate to ask us. For a detailed manual just click here."
 let linkTextWithColor = "click here"

 let range = (text as NSString).rangeOfString(linkTextWithColor)

 let attributedString = NSMutableAttributedString(string:text)
 attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor() , range: range)

 self.helpText.attributedText = attributedString

self.helpTextadalah jalan UILabelkeluar.

Chris
sumber
1
Oh Chris, kamu adalah pahlawanku. Saya mencari blok kode ini untuk waktu yang lama.
Pan Mluvčí
@tokopedia Saya ingin mengubah nsmutableattributed string dalam textview, apakah itu mungkin
Uma Madhavi
Ini berfungsi untuk satu kata. tetapi dalam string saya ada beberapa kata itu berubah warnanya tetapi kemudian saya menulis setelah kata warna merah itu warna kata itu juga merah. jadi Anda dapat memberikan solusi apa pun jika Anda punya.
Dhaval Solanki
Terima kasih untuk bantuannya!
ssowri1
18

Swift 4.2 dan Swift 5 mewarnai bagian string.

Cara yang sangat mudah untuk menggunakan NSMutableAttributedString sambil memperluas String. Ini juga dapat digunakan untuk mewarnai lebih dari satu kata di seluruh string.

Tambahkan file baru untuk ekstensi, File -> New -> Swift File dengan nama ex. "NSAttributedString + TextColouring" dan tambahkan kodenya

import UIKit

extension String {
    func attributedStringWithColor(_ strings: [String], color: UIColor, characterSpacing: UInt? = nil) -> NSAttributedString {
        let attributedString = NSMutableAttributedString(string: self)
        for string in strings {
            let range = (self as NSString).range(of: string)
            attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: color, range: range)
        }

        guard let characterSpacing = characterSpacing else {return attributedString}

        attributedString.addAttribute(NSAttributedString.Key.kern, value: characterSpacing, range: NSRange(location: 0, length: attributedString.length))

        return attributedString
    }
}

Sekarang Anda dapat menggunakan secara global di setiap viewcontroller yang Anda inginkan:

let attributedWithTextColor: NSAttributedString = "Doc, welcome back :)".attributedStringWithColor(["Doc", "back"], color: UIColor.black)

myLabel.attributedText = attributedWithTextColor

Contoh penggunaan pewarnaan teks dengan swift 4

Doci
sumber
11

Jawaban sudah diberikan di posting sebelumnya tetapi saya memiliki cara berbeda untuk melakukan ini

Swift 3x:

var myMutableString = NSMutableAttributedString()

myMutableString = NSMutableAttributedString(string: "Your full label textString")

myMutableString.setAttributes([NSFontAttributeName : UIFont(name: "HelveticaNeue-Light", size: CGFloat(17.0))!
        , NSForegroundColorAttributeName : UIColor(red: 232 / 255.0, green: 117 / 255.0, blue: 40 / 255.0, alpha: 1.0)], range: NSRange(location:12,length:8)) // What ever range you want to give

yourLabel.attributedText = myMutableString

Semoga ini bisa membantu siapa saja!

Anurag Sharma
sumber
@UmaMadhavi Apa kebutuhan Anda sebenarnya?
Anurag Sharma
Saya ingin mengubah ukuran font & warna font di textview. Saya mendapatkannya di nsmutableattributedstring.
Uma Madhavi
@UmaMadhavi lihat link1 dan link2 ini . Mungkin membantu!
Anurag Sharma
Mogok jika font tidak tersedia.
SafeFastExpressive
10

Jawaban Chris sangat membantu saya, jadi saya menggunakan pendekatannya dan berubah menjadi fungsi yang dapat saya gunakan kembali. Ini mari saya menetapkan warna ke substring sambil memberi sisa string warna lain.

static func createAttributedString(fullString: String, fullStringColor: UIColor, subString: String, subStringColor: UIColor) -> NSMutableAttributedString
{
    let range = (fullString as NSString).rangeOfString(subString)
    let attributedString = NSMutableAttributedString(string:fullString)
    attributedString.addAttribute(NSForegroundColorAttributeName, value: fullStringColor, range: NSRange(location: 0, length: fullString.characters.count))
    attributedString.addAttribute(NSForegroundColorAttributeName, value: subStringColor, range: range)
    return attributedString
}
ghostatron
sumber
6

Swift 4.1.0

NSAttributedStringKey.foregroundColor

misalnya jika Anda ingin mengubah font di NavBar:

self.navigationController?.navigationBar.titleTextAttributes = [ NSAttributedStringKey.font: UIFont.systemFont(ofSize: 22), NSAttributedStringKey.foregroundColor: UIColor.white]
swift2geek
sumber
6

Anda dapat menggunakan ekstensi ini, saya mengujinya

cepat 4.2

import Foundation
import UIKit

extension NSMutableAttributedString {

    convenience init (fullString: String, fullStringColor: UIColor, subString: String, subStringColor: UIColor) {
           let rangeOfSubString = (fullString as NSString).range(of: subString)
           let rangeOfFullString = NSRange(location: 0, length: fullString.count)//fullString.range(of: fullString)
           let attributedString = NSMutableAttributedString(string:fullString)
           attributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: fullStringColor, range: rangeOfFullString)
           attributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: subStringColor, range: rangeOfSubString)

           self.init(attributedString: attributedString)
   }

}
Amr Marah
sumber
4

Swift 2.2.0

var myMutableString = NSMutableAttributedString()

myMutableString = NSMutableAttributedString(string: "1234567890", attributes: [NSFontAttributeName:UIFont(name: kDefaultFontName, size: 14.0)!])

myMutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor(red: 0.0/255.0, green: 125.0/255.0, blue: 179.0/255.0, alpha: 1.0), range: NSRange(location:0,length:5))

self.lblPhone.attributedText = myMutableString
Sarabjit Singh
sumber
Saya mendapatkan kesalahan saat melakukan ini. Saya pikir Anda menginginkan ini tanpa .CGColor.
Bjorn Roche
@Rumahsakitotak. bagaimana ini bisa dimungkinkan untuk textview
Uma Madhavi
@UmaMadhavi ... Anda hanya perlu menambahkan self.textView.attributedText = myMutableString ..... Ini akan bekerja ...
Sarabjit Singh
4

Cara termudah untuk melakukan label dengan gaya berbeda seperti warna, font, dll adalah menggunakan properti "Attributed" di Attributes Inspector. Cukup pilih bagian teks dan ubah seperti yang Anda inginkan

masukkan deskripsi gambar di sini

jMelvins
sumber
1
Misalkan Anda tidak mengubah string secara terprogram
Alejandro Cumpa
4

Berdasarkan jawaban sebelum saya membuat ekstensi string

extension String {

func highlightWordsIn(highlightedWords: String, attributes: [[NSAttributedStringKey: Any]]) -> NSMutableAttributedString {
     let range = (self as NSString).range(of: highlightedWords)
     let result = NSMutableAttributedString(string: self)

     for attribute in attributes {
         result.addAttributes(attribute, range: range)
     }

     return result
    }
}

Anda bisa meneruskan atribut teks ke metode

Panggil seperti ini

  let attributes = [[NSAttributedStringKey.foregroundColor:UIColor.red], [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 17)]]
  myLabel.attributedText = "This is a text".highlightWordsIn(highlightedWords: "is a text", attributes: attributes)
kuzdu
sumber
4

Swift 4.1.0

Saya telah berubah dari ini Di Swift 3

let str = "Welcome "
let welcomeAttribute = [ NSForegroundColorAttributeName: UIColor.blue()]
let welcomeAttrString = NSMutableAttributedString(string: str, attributes: welcomeAttribute)

Dan ini di Swift 4.0

let str = "Welcome "
let welcomeAttribute = [ NSAttributedStringKey.foregroundColor: UIColor.blue()]
let welcomeAttrString = NSMutableAttributedString(string: str, attributes: welcomeAttribute)

ke Swift 4.1

let str = "Welcome "
let welcomeAttribute = [ NSAttributedStringKey(rawValue: NSForegroundColorAttributeName): UIColor.blue()]
let welcomeAttrString = NSMutableAttributedString(string: str, attributes: welcomeAttribute)

Bekerja dengan baik

niravdesai21.dll
sumber
Ini mengubah seluruh string? Ini yang paling mudah dibaca oleh saya, tetapi Adakah cara untuk mengubah hanya kata-kata tertentu dalam string seperti yang diminta OP.
Moondra
3

cepat 4.2

    let textString = "Hello world"
    let range = (textString as NSString).range(of: "world")
    let attributedString = NSMutableAttributedString(string: textString)

    attributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.red, range: range)
    self.textUIlable.attributedText = attributedString
Giang
sumber
2

Untuk semua orang yang mencari " Menerapkan warna tertentu ke beberapa kata dalam teks ", kami dapat melakukannya menggunakan NSRegularExpression

 func highlight(matchingText: String, in text: String) {
    let attributedString  = NSMutableAttributedString(string: text)
    if let regularExpression = try? NSRegularExpression(pattern: "\(matchingText)", options: .caseInsensitive) {
        let matchedResults = regularExpression.matches(in: text, options: [], range: NSRange(location: 0, length: attributedString.length))
        for matched in matchedResults {
             attributedString.addAttributes([NSAttributedStringKey.backgroundColor : UIColor.yellow], range: matched.range)

        }
        yourLabel.attributedText = attributedString
    }
}

Tautan referensi: https://gist.github.com/aquajach/4d9398b95a748fd37e88

cgeek
sumber
Apakah mungkin menggunakan kode Anda di aplikasi kakao MacOS? Saya mencoba menggunakannya dalam proyek kakao saya, tetapi tidak ada .attributedText di cocoa NSTextView.
CaOs433
2

Ini mungkin berhasil untuk Anda

let main_string = " User not found,Want to review ? Click here"
    let string_to_color = "Click here"

    let range = (main_string as NSString).range(of: string_to_color)

    let attribute = NSMutableAttributedString.init(string: main_string)
    attribute.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.blue , range: range)

    lblClickHere.attributedText = attribute
Davender Verma
sumber
1
Meskipun cuplikan kode ini dapat menjadi solusinya, menyertakan penjelasan sangat membantu meningkatkan kualitas posting Anda. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa mendatang, dan orang-orang itu mungkin tidak tahu alasan saran kode Anda.
HMD
2

Dengan fungsi sederhana ini Anda dapat menetapkan teks dan menyorot kata yang dipilih.

Anda juga dapat mengubah UITextView menjadi UILabel , dll.

func highlightBoldWordAtLabel(textViewTotransform: UITextView, completeText: String, wordToBold: String){
    textViewToTransform.text = completeText
    let range = (completeText as NSString).range(of: wordToBold)
    let attribute = NSMutableAttributedString.init(string: completeText)

    attribute.addAttribute(NSAttributedString.Key.font, value: UIFont.boldSystemFont(ofSize: 16), range: range)
    attribute.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.black , range: range)
    textViewToTransform.attributedText = attribute
}
Dan Pengembang
sumber
1

Untuk mengubah warna warna font, pertama-tama pilih atribut daripada polos seperti pada gambar di bawah

Anda kemudian perlu memilih teks di bidang atribut dan kemudian memilih tombol warna di sisi kanan perataan. Ini akan mengubah warnanya.

Kingsley Mitchell
sumber
1

Anda bisa menggunakan metode ini. Saya menerapkan metode ini di kelas utilitas umum saya untuk mengakses secara global.

func attributedString(with highlightString: String, normalString: String, highlightColor: UIColor) -> NSMutableAttributedString {
    let attributes = [NSAttributedString.Key.foregroundColor: highlightColor]
    let attributedString = NSMutableAttributedString(string: highlightString, attributes: attributes)
    attributedString.append(NSAttributedString(string: normalString))
    return attributedString
}
nitin.agam
sumber
0

Jika Anda menggunakan Swift 3x dan UITextView, mungkin NSForegroundColorAttributeName tidak akan berfungsi (tidak berhasil untuk saya apa pun pendekatan yang saya coba).

Jadi, setelah beberapa penggalian, saya menemukan solusi.

//Get the textView somehow
let textView = UITextView()
//Set the attributed string with links to it
textView.attributedString = attributedString
//Set the tint color. It will apply to the link only
textView.tintColor = UIColor.red
mcastro
sumber
0

Cara super mudah untuk melakukan ini.

let text = "This is a colorful attributed string"
let attributedText = 
NSMutableAttributedString.getAttributedString(fromString: text)
attributedText.apply(color: .red, subString: "This")
//Apply yellow color on range
attributedText.apply(color: .yellow, onRange: NSMakeRange(5, 4))

Untuk detail lebih lanjut klik di sini: https://github.com/iOSTechHub/AttributedString

Ashish Chauhan
sumber
0

Anda perlu mengubah parameter textview, bukan parameter string yang diatribusikan

textView.linkTextAttributes = [
        NSAttributedString.Key.foregroundColor: UIColor.red,
        NSAttributedString.Key.underlineColor: UIColor.red,
        NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue
    ]
Maxvale
sumber
0

Silakan periksa cocoapod Prestyler :

Prestyler.defineRule("$", UIColor.orange)
label.attributedText = "This $text$ is orange".prestyled()
Kruiller
sumber
0
extension String{
// to make text field mandatory * looks
mutating func markAsMandatoryField()-> NSAttributedString{

    let main_string = self
    let string_to_color = "*"
    let range = (main_string as NSString).range(of: string_to_color)
    print("The rang = \(range)")
    let attribute = NSMutableAttributedString.init(string: main_string)
    attribute.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.rgbColor(red: 255.0, green: 0.0, blue: 23.0) , range: range)
     return attribute
}

}

gunakan EmailLbl.attributedText = EmailLbl.text! .markAsMandatoryField ()

NSurajit
sumber
0

Anda dapat menggunakan ekstensi sederhana

extension String{

func attributedString(subStr: String) -> NSMutableAttributedString{
    let range = (self as NSString).range(of: subStr)
    let attributedString = NSMutableAttributedString(string:self)
    attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red , range: range)
    
    return attributedString
  }
}

myLable.attributedText = fullStr.attributedString(subStr: strToChange)

  
Waliyan
sumber