Thay đổi màu của văn bản cụ thể bằng NSMutableAttributedString trong Swift


100

Vấn đề tôi đang gặp phải là tôi muốn có thể thay đổi màu văn bản của văn bản nhất định trong TextView. Tôi đang sử dụng một chuỗi được nối và chỉ muốn các chuỗi tôi đang nối vào văn bản của TextView. Có vẻ như những gì tôi muốn sử dụng là NSMutableAttributedString, nhưng tôi không tìm thấy bất kỳ tài nguyên nào về cách sử dụng điều này trong Swift. Những gì tôi có cho đến nay là một cái gì đó như thế này:

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

Từ đây, tôi biết mình cần tìm phạm vi các từ cần thay đổi Màu văn bản của chúng và sau đó thêm chúng vào chuỗi phân bổ. Những gì tôi cần biết là làm thế nào để tìm các chuỗi chính xác từ chuỗi phân bổ và sau đó thay đổi màu văn bản của chúng.

Vì tôi có xếp hạng quá thấp nên tôi không thể trả lời câu hỏi của chính mình, nhưng đây là câu trả lời tôi đã tìm thấy

Tôi đã tìm thấy câu trả lời của riêng mình bằng cách dịch từ dịch một số mã từ

Thay đổi thuộc tính của chuỗi con trong NSAttributedString

Đây là ví dụ về triển khai trong 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

Vì tôi muốn thay đổi Màu văn bản của nhiều Chuỗi, tôi sẽ tạo một hàm trợ giúp để xử lý điều này, nhưng điều này có tác dụng với việc thay đổi Màu văn bản.


Bạn có biết làm thế nào để làm điều đó trong Objective-C? Bạn đã thử viết lại mã đó bằng Swift chưa?
Aaron Brager

Đây là một câu trả lời thực sự tốt: stackoverflow.com/a/37992022/426571
el_quick

Câu trả lời:


110

Tôi thấy bạn đã trả lời câu hỏi phần nào, nhưng để cung cấp một cách ngắn gọn hơn một chút mà không sử dụng regex để trả lời cho câu hỏi tiêu đề:

Để thay đổi màu của độ dài văn bản, bạn cần biết chỉ số bắt đầu và kết thúc của các ký tự được tô màu trong chuỗi, ví dụ:

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

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

Sau đó, bạn chuyển đổi thành chuỗi phân bổ và sử dụng 'thêm thuộc tính' với NSForegroundColorAttributeName:

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

Có thể tìm thấy danh sách các thuộc tính tiêu chuẩn khác mà bạn có thể đặt trong tài liệu của Apple


20
NSColor là OSX chỉ - sử dụng UIColor cho IOS
Steve O'Connor

1
Điều gì sẽ xảy ra nếu tôi có var main_string = "Xin chào Thế giới Xin chào Thế giới Xin chào Thế giới" và tôi cần áp dụng màu cho "Thế giới" trong toàn bộ chuỗi?
msmq

main_string, string_to_colorrangekhông bao giờ bị đột biến. Cân nhắc thay đổi chúng thành lethằng số?
Cesare

Giải pháp tốt. Bạn đã cứu ngày của tôi.
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

điều gì sẽ xảy ra nếu chuỗi lớn và có nhiều từ trùng lặp (tương tự). phạm vi (trong số: ...) sẽ hoạt động?
Hatim

44

Cập nhật 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.helpTextlà một UILabellối thoát.


1
Ôi Chris, bạn là người hùng của tôi. Tôi đang tìm kiếm khối mã chính xác này trong một thời gian dài.
Pan Mluvčí

@chris. Tôi muốn thay đổi chuỗi nsmutableattributed trong TextView, là có thể
Uma Madhavi

Nó hoạt động cho từ đơn lẻ. nhưng trong chuỗi của tôi có nhiều từ nó thay đổi màu sắc nhưng sau đó tôi viết sau từ màu đỏ đó màu của từ đó cũng là màu đỏ. bạn có thể đưa ra giải pháp nào nếu có.
Dhaval Solanki

Cảm ơn sự giúp đỡ của bạn!
ssowri1

18

Swift 4.2Swift 5 tô màu các phần của chuỗi.

Một cách rất dễ dàng để sử dụng NSMutableAttributedString trong khi mở rộng chuỗi. Điều này cũng có thể được sử dụng để tô màu nhiều hơn một từ trong toàn bộ chuỗi.

Thêm tệp mới cho các phần mở rộng, Tệp -> Mới -> Tệp Swift với tên cho tệp cũ. "NSAttributedString + TextColouring" và thêm mã

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

Bây giờ bạn có thể sử dụng toàn cầu tại bất kỳ bộ điều khiển chế độ xem nào bạn muốn:

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

myLabel.attributedText = attributedWithTextColor

Ví dụ về cách sử dụng màu văn bản với swift 4


11

Câu trả lời đã được đưa ra trong các bài viết trước nhưng tôi có một cách khác để làm điều này

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

Hy vọng điều này sẽ giúp bất kỳ ai!


@UmaMadhavi Yêu cầu của bạn chính xác là gì?
Anurag Sharma

Tôi muốn thay đổi kích thước phông chữ và màu phông chữ trong chế độ xem văn bản. Tôi đang nhận được nó trong nsmutableattributedstring.
Uma Madhavi

@UmaMadhavi hãy xem link1link2 này . Nó có thể hữu ích!
Anurag Sharma

Sự cố nếu không có phông chữ.
SafeFastExpressive

10

Câu trả lời của Chris đã giúp ích rất nhiều cho tôi, vì vậy tôi đã sử dụng cách tiếp cận của anh ấy và biến thành một func mà tôi có thể sử dụng lại. Điều này cho phép tôi gán một màu cho một chuỗi con trong khi cung cấp cho phần còn lại của chuỗi một màu khác.

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
}

6

Swift 4.1

NSAttributedStringKey.foregroundColor

ví dụ nếu bạn muốn thay đổi phông chữ trong NavBar:

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

6

Bạn có thể sử dụng tiện ích mở rộng này, tôi đã thử nghiệm nó

nhanh chóng 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)
   }

}

4

Swift 2.2

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

Tôi gặp lỗi khi làm điều này. Tôi nghĩ bạn muốn điều này mà không cần .CGColor.
Bjorn Roche

@SarabjitSingh. như thế nào có thể đây là có thể cho TextView
Uma Madhavi

@UmaMadhavi ... Bạn chỉ cần thêm self.textView.attributedText = myMutableString ..... Nó sẽ hoạt động ...
Sarabjit Singh

4

Cách dễ nhất để tạo nhãn với các kiểu khác nhau như màu sắc, phông chữ, v.v. là sử dụng thuộc tính "Thuộc tính" trong Trình kiểm tra thuộc tính. Chỉ cần chọn một phần của văn bản và thay đổi nó như bạn muốn

nhập mô tả hình ảnh ở đây


1
Suposing bạn không thay đổi chuỗi programatically
Alejandro Cumpa

4

Dựa trên các câu trả lời trước khi tôi tạo phần mở rộng chuỗi

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

Bạn có thể chuyển các thuộc tính cho văn bản vào phương thức

Gọi như thế này

  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)

4

Swift 4.1

Tôi đã thay đổi từ điều này trong Swift 3

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

Và điều này trong Swift 4.0

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

sang Swift 4.1

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

Hoạt động tốt


Điều này đang thay đổi toàn bộ chuỗi? Đây là cách dễ đọc nhất đối với tôi, nhưng Có cách nào để chỉ thay đổi các từ cụ thể trong chuỗi như OP đã hỏi.
Moondra

3

nhanh chóng 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

2

Đối với tất cả những ai đang tìm kiếm " Áp dụng màu cụ thể cho nhiều từ trong văn bản ", chúng tôi có thể thực hiện bằng cách sử dụng 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
    }
}

Link tham khảo: https://gist.github.com/aquajach/4d9398b95a748fd37e88


Có thể sử dụng mã của bạn trong ứng dụng ca cao MacOS không? Tôi đã cố gắng sử dụng nó trong dự án ca cao của mình, nhưng không có .attributedText trong NSTextView ca cao.
CaOs433

2

Điều này có thể phù hợp với bạn

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

1
Mặc dù đoạn mã này có thể là giải pháp, nhưng bao gồm phần giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho người đọc trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn.
HMD

2

Với chức năng đơn giản này, bạn có thể gán văn bản và đánh dấu từ đã chọn.

Bạn cũng có thể thay đổi UITextView thành UILabel , v.v.

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
}

1

Để thay đổi màu sắc của phông chữ, trước tiên hãy chọn thuộc tính thay vì đơn giản như trong hình ảnh bên dưới

Sau đó, bạn cần chọn văn bản trong trường phân bổ và sau đó chọn nút màu ở phía bên phải của căn chỉnh. Điều này sẽ thay đổi màu sắc.


1

Bạn có thể sử dụng phương pháp này. Tôi đã triển khai phương pháp này trong lớp tiện ích chung của mình để truy cập trên toàn cầu.

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
}

0

Nếu bạn đang sử dụng Swift 3x và UITextView, có thể NSForegroundColorAttributeName sẽ không hoạt động (nó không hoạt động với tôi cho dù tôi đã thử cách tiếp cận nào).

Vì vậy, sau khi tìm hiểu kỹ, tôi đã tìm ra giải pháp.

//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

0

Cách siêu dễ dàng để làm điều này.

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

Để biết thêm chi tiết, hãy nhấp vào đây: https://github.com/iOSTechHub/AttributedString


0

Bạn cần thay đổi thông số textview, không phải tham số của chuỗi phân bổ

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

0

Vui lòng kiểm tra cocoapod Prestyler :

Prestyler.defineRule("$", UIColor.orange)
label.attributedText = "This $text$ is orange".prestyled()

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
}

}

sử dụng EmailLbl.attributedText = EmailLbl.text! .markAsMandatoryField ()


0

Bạn có thể sử dụng như một tiện ích mở rộng đơn giản

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)

  
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.