简体   繁体   English

在 Swift 中使用 NSMutableAttributedString 更改特定文本的颜色

[英]Changing specific text's color using NSMutableAttributedString in Swift

The issue I am having is that I want to be able to change the textColor of certain text in a TextView.我遇到的问题是我希望能够更改 TextView 中某些文本的 textColor。 I am using a concatenated string, and just want the strings I am appending into the TextView's text.我正在使用连接字符串,并且只想要我附加到 TextView 文本中的字符串。 It appears that what I want to use is NSMutableAttributedString , but I am not finding any resources of how to use this in Swift.看来我想使用的是NSMutableAttributedString ,但我没有找到有关如何在 Swift 中使用它的任何资源。 What I have so far is something like this:到目前为止,我所拥有的是这样的:

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

From here I know I need to find the range of words that need to have their textColor changed and then add them to the attributed string.从这里我知道我需要找到需要更改 textColor 的单词范围,然后将它们添加到属性字符串中。 What I need to know is how to find the correct strings from the attributedString, and then change their textColor.我需要知道的是如何从attributedString 中找到正确的字符串,然后更改它们的textColor。

Since I have too low of a rating I can't answer my own question, but here is the answer I found由于我的评分太低,我无法回答我自己的问题,但这是我找到的答案

I found my own answer by translating from translating some code from我通过翻译一些代码找到了自己的答案

Change attributes of substrings in a NSAttributedString 更改 NSAttributedString 中子字符串的属性

Here is the example of implementation in Swift:这是在 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

Since I am wanting to change the textColor of multiple Strings I will make a helper function to handle this, but this works for changing the textColor.由于我想更改多个字符串的 textColor,因此我将创建一个辅助函数来处理此问题,但这适用于更改 textColor。

let mainString = "Hello World"
let stringToColor = "World"

SWIFT 5快速 5

let range = (mainString as NSString).range(of: stringToColor)

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

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

SWIFT 4.2斯威夫特 4.2

let range = (mainString as NSString).range(of: stringToColor)
    

let mutableAttributedString = NSMutableAttributedString.init(string: mainString)
mutableAttributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.red, range: range)     
    
textField = UITextField.init(frame: CGRect(x:10, y:20, width:100, height: 100))
textField.attributedText = mutableAttributedString

I see you have answered the question somewhat, but to provide a slightly more concise way without using regex to answer to the title question:我看到你已经回答了这个问题,但提供一种更简洁的方式,而不使用正则表达式来回答标题问题:

To change the colour of a length of text you need to know the start and end index of the coloured-to-be characters in the string eg要更改一段文本的颜色,您需要知道字符串中待着色字符的开始和结束索引,例如

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

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

Then you convert to attributed string and use 'add attribute' with NSForegroundColorAttributeName:然后转换为属性字符串并使用带有 NSForegroundColorAttributeName 的“添加属性”:

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

A list of further standard attributes you can set can be found in Apple's documentation您可以在Apple 的文档中找到您可以设置的更多标准属性列表

Swift 2.1 Update:斯威夫特 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.helpText is a UILabel outlet. self.helpText是一个UILabel插座。

Swift 4.2 and Swift 5 colorise parts of the string. Swift 4.2Swift 5为字符串的部分着色。

A very easy way to use NSMutableAttributedString while extending the String.在扩展字符串时使用 NSMutableAttributedString 的一种非常简单的方法。 This also can be used to colourize more than one word in the whole string.这也可用于为整个字符串中的多个单词着色。

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

Now you can use globally at any viewcontroller you want:现在你可以在任何你想要的视图控制器上全局使用:

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

myLabel.attributedText = attributedWithTextColor

在 swift 4 中使用文本着色的示例

Answer is already given in previous posts but i have a different way of doing this以前的帖子中已经给出了答案,但我有不同的方法来做到这一点

Swift 3x :斯威夫特 3 倍:

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

Hope this helps anybody!希望这可以帮助任何人!

Chris' answer was a great help to me, so I used his approach and turned into a func that I can reuse. Chris 的回答对我帮助很大,所以我使用了他的方法并变成了一个我可以重用的 func。 This let's me assign a color to a substring while giving the rest of the string another color.这让我为子字符串分配一种颜色,同时为字符串的其余部分提供另一种颜色。

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
}

Swift 4.1斯威夫特 4.1

NSAttributedStringKey.foregroundColor

for example if you want to change font in NavBar:例如,如果您想更改 NavBar 中的字体:

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

You can use this extension I test it over你可以使用我测试过的这个扩展

swift 4.2快速 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)
   }

}

Swift 2.2斯威夫特 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

Easiest way to do label with different style such as color, font etc. is use property "Attributed" in Attributes Inspector.使用不同样式(如颜色、字体等)做标签的最简单方法是在 Attributes Inspector 中使用属性“Attributed”。 Just choose part of text and change it like you want只需选择部分文本并根据需要进行更改

在此处输入图片说明

Based on the answers before I created a string extension基于我创建字符串扩展之前的答案

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

You can pass the attributes for the text to the method您可以将文本的属性传递给方法

Call like this像这样打电话

  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)

Swift 4.1斯威夫特 4.1

I have changed from this In Swift 3我已经从这个 In Swift 3 改变了

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

And this in Swift 4.0这在 Swift 4.0 中

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

to Swift 4.1Swift 4.1

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

Works fine工作正常

swift 4.2快速 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

This might be work for you这可能适合你

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

With this simple function you can assign the text and highlight the chosen word.使用这个简单的功能,您可以分配文本并突出显示所选单词。

You can also change the UITextView to UILabel , etc.您还可以将UITextView更改为UILabel等。

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
}

For everyone who are looking for " Applying specific color to multiple words in text ", we can do it using NSRegularExpression对于正在寻找“将特定颜色应用于文本中的多个单词”的每个人,我们可以使用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
    }
}

Reference link : https://gist.github.com/aquajach/4d9398b95a748fd37e88参考链接: https : //gist.github.com/aquajach/4d9398b95a748fd37e88

You can use as simple extension您可以使用简单的扩展

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)

  

This extension works well when configuring the text of a label with an already set default color.当使用已设置的默认颜色配置标签文本时,此扩展程序运行良好。

public extension String {
    func setColor(_ color: UIColor, ofSubstring substring: String) -> NSMutableAttributedString {
        let range = (self as NSString).range(of: substring)
        let attributedString = NSMutableAttributedString(string: self)
        attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: color, range: range)
        return attributedString
    }
}

For example例如

let text = "Hello World!"
let attributedText = text.setColor(.blue, ofSubstring: "World")

let myLabel = UILabel()
myLabel.textColor = .white
myLabel.attributedText = attributedText

To change color of the font colour, first select attributed instead of plain like in the image below要更改字体颜色的颜色,请先选择下图所示的属性而不是普通颜色

You then need to select the text in the attributed field and then select the color button on the right-hand side of the alignments.然后,您需要选择属性字段中的文本,然后选择路线右侧的颜色按钮。 This will change the color.这将改变颜色。

Super easy way to do this.超级简单的方法来做到这一点。

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

For more detail click here: https://github.com/iOSTechHub/AttributedString有关更多详细信息,请单击此处: https : //github.com/iOSTechHub/AttributedString

You can use this method.您可以使用此方法。 I implemented this method in my common utility class to access globally.我在通用实用程序类中实现了此方法以进行全局访问。

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
}

If you are using Swift 3x and UITextView, maybe the NSForegroundColorAttributeName won't work (it didn't work for me no matter what approach I tried).如果您使用的是 Swift 3x 和 UITextView,则 NSForegroundColorAttributeName 可能不起作用(无论我尝试过什么方法,它对我都不起作用)。

So, after some digging around I found a solution.所以,经过一番挖掘,我找到了一个解决方案。

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

You need to change textview parameters, not parameters of attributed string您需要更改 textview 参数,而不是属性字符串的参数

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

Please check cocoapod Prestyler :请检查 cocoapod Prestyler

Prestyler.defineRule("$", UIColor.orange)
label.attributedText = "This $text$ is orange".prestyled()
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
}

} }

use EmailLbl.attributedText = EmailLbl.text!.markAsMandatoryField()使用 EmailLbl.attributedText = EmailLbl.text!.markAsMandatoryField()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM