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


100

我遇到的问题是我希望能够更改TextView中某些文本的textColor。我使用的是串联字符串,只希望将字符串追加到TextView的文本中。看来我想使用的是NSMutableAttributedString,但是在Swift中找不到如何使用它的任何资源。到目前为止,我有这样的事情:

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

从这里我知道我需要找到需要更改其textColor的单词范围,然后将它们添加到属性字符串中。我需要知道的是如何从attributedString中查找正确的字符串,然后更改其textColor。

由于我的评分太低,我无法回答自己的问题,但这是我找到的答案

我通过翻译一些代码来找到自己的答案

更改NSAttributedString中子字符串的属性

这是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

由于我想更改多个字符串的textColor,因此我将创建一个辅助函数来处理此问题,但这可用于更改textColor。


您知道如何在Objective-C中做到这一点吗?您是否尝试过在Swift中重写相同的代码?
亚伦·布拉格

这是一个非常不错的答案:stackoverflow.com/a/37992022/426571
el_quick

Answers:


110

我看到您已经在某种程度上回答了这个问题,但是提供了一种更简洁的方法,而无需使用正则表达式来回答标题问题:

要更改文本长度的颜色,您需要知道字符串中有色字符的开始和结束索引,例如

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

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

然后,您可以转换为属性字符串,并在NSForegroundColorAttributeName中使用'add attribute':

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

您可以设置的其他标准属性的列表可在Apple文档中找到


20
NSColor仅是OSX-将UIColor用于IOS
Steve O'Connor

1
如果我有var main_string =“ Hello World Hello World Hello World”,并且我需要在整个字符串中对“ World”应用颜色怎么办?
msmq

main_stringstring_to_color并且range从未突变。考虑将其更改为let常数?
切萨雷

不错的解决方案。你救了我的一天。
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

如果字符串很大,并且有很多重复(相似)的单词,该怎么办。范围(...)会起作用吗?
哈蒂姆

44

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.helpText是一个UILabel出口。


1
克里斯,你是我的英雄。我一直在寻找这个确切的代码块。
PanMluvčí16年

@克里斯 。我想在textview中更改nsmutableattributed字符串,这是否可能
Uma Madhavi

它适用于单个单词。但是在我的字符串中有多个单词,它的颜色是变化的,但是我在那个红色单词之后写出单词的颜色也是红色的。
Dhaval Solanki '18

谢谢您的帮助!
ssowri1

18

Swift 4.2Swift 5为字符串的一部分着色。

在扩展String时使用NSMutableAttributedString的一种非常简单的方法。这也可以用于给整个字符串中的多个单词上色。

为扩展名添加新文件,文件->新建-> Swift文件,名称为ex。“ NSAttributedString + TextColouring”并添加代码

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

现在,您可以在所需的任何视图控制器上全局使用:

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

myLabel.attributedText = attributedWithTextColor

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


11

以前的帖子中已经给出了答案,但是我有不同的方法

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

希望这对任何人有帮助!


@UmaMadhavi您到底有什么要求?
阿努拉格·夏尔马

我想在textview中更改字体大小和字体颜色。我在nsmutableattributedstring中得到它。
Uma Madhavi

@UmaMadhavi检出此link1link2。可能会有帮助!
阿努拉格·夏尔马

如果没有字体会崩溃。
SafeFastExpressive

10

克里斯的回答对我有很大帮助,因此我使用了他的方法,并变成了可以重用的功能。这让我为子字符串分配一种颜色,同时为字符串的其余部分提供另一种颜色。

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

斯威夫特4.1

NSAttributedStringKey.foregroundColor

例如,如果您想更改NavBar中的字体:

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

6

您可以使用此扩展程序,我将对其进行测试

迅捷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

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

执行此操作时出现错误。我想你要这个没有.CGColor
比约恩·罗氏

@SarabjitSingh。文本视图如何做到这一点
Uma Madhavi

@UmaMadhavi ...您只需要添加self.textView.attributedText = myMutableString .....它将起作用...
Sarabjit Singh

4

制作具有不同样式(例如颜色,字体等)的标签的最简单方法是使用Attributes Inspector中的属性“ Attributed”。只需选择文本的一部分并根据需要进行更改

在此处输入图片说明


1
假设您没有以编程方式更改字符串
Alejandro Cumpa '18

4

根据我创建字符串扩展名之前的答案

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

您可以将文本的属性传递给方法

像这样打电话

  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

斯威夫特4.1

我已经从In Swift 3更改了

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

而这在Swift 4.0中

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

Swift 4.1

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

工作良好


这会改变整个字符串吗?这对我来说是最易读的,但是有没有办法像OP那样仅更改字符串中的特定单词。
Moondra

3

迅捷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

对于正在寻找“ 将特定颜色应用于文本中的多个单词 ”的每个人,我们都可以使用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
    }
}

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


是否可以在MacOS可可应用中使用您的代码?我尝试在可可项目中使用它,但是可可NSTextView中没有.attributedText。
CaOs433 '18

2

这可能对你有用

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
尽管此代码段可能是解决方案,但包括说明确实有助于提高帖子的质量。请记住,您将来会为读者回答这个问题,而这些人可能不知道您提出代码建议的原因。
HMD

2

使用此简单功能,您可以分配文本并突出显示所选单词。

您也可以将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
}

1

要更改字体颜色的颜色,请首先选择属性而非下图所示的普通颜色

然后,您需要在属性字段中选择文本,然后选择路线右侧的颜色按钮。这将改变颜色。


1

您可以使用此方法。我在通用工具类中实现了此方法以全局访问。

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

如果您使用的是Swift 3x和UITextView,则NSForegroundColorAttributeName可能不起作用(无论我尝试哪种方法,它都对我不起作用)。

因此,经过一番挖掘,我找到了解决方案。

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

超级简单的方法做到这一点。

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

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


0

您需要更改textview参数,而不是属性字符串的参数

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

0

请检查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
}

}

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


0

您可以使用简单的扩展名

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)

  
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.