ios - 如何为 UITextView 中的特定单词设置样式?

标签 ios swift string xcode uitextview

我有一个 UITextView,我试图在其中设置特定单词的样式。我面临的问题是,在为单词设置样式时,它还会将该样式应用到该单词的所有其他出现位置。我只希望单词“第一”或“第三”的一个特定实例具有自定义样式。

考虑 UITextView 中存在的文本。

Sunset is the time of day when our sky meets the outer space solar winds. 
There are blue, pink, and purple swirls, spinning and twisting, like clouds of balloons caught in
a whirlwind. The sun moves slowly to hide behind the line of horizon, while the 
moon races to take its place in prominence atop the night sky. People slow to a crawl, 
entranced, fully forgetting the deeds that must still be done. There is a coolness, a 
calmness, when the sun does set.

如果我将样式设置为 sun,则该单词的两次出现都会应用该样式。

这是代码

let normalAttr = [NSAttributedString.Key.font: UIFont(name: "Oswald", size: 19.0), NSAttributedString.Key.paragraphStyle : style]
let customAttr = [NSAttributedString.Key.font: UIFont(name: "Oswald", size: 19.0), NSAttributedString.Key.foregroundColor: UIColor.red]
let words = textView.text.components(separatedBy: " ")
let newText = NSMutableAttributedString()
for word in words {
   if (word == selectedWord) {
     newText.append(NSMutableAttributedString(string: word + " " , attributes: selectedAttributes as [NSAttributedString.Key : Any]))
   } else {
     newText.append(NSMutableAttributedString(string:word + " ", attributes: normalAttributes as [NSAttributedString.Key : Any]))
   }
 }
textView.attributedText = newText

我只想将样式应用于一个单词,有什么帮助我可以做到这一点吗?

最佳答案

您如何选择要替换的实例?

最简单的方法是只维护自己的计数器:

var counter = 0
for word in words {
   if (word == selectedWord) {
     counter += 1
      // myTarget being the first or third or whatever
     let attributesToUse = (counter == myTarget) ? selectedAttributes : normalAttributes
     newText.append(NSMutableAttributedString(string: word + " " , attributes: attributesToUse as [NSAttributedString.Key : Any]))
   } else {
     newText.append(NSMutableAttributedString(string:word + " ", attributes: normalAttributes as [NSAttributedString.Key : Any]))
   }
 }

但是你当然可以通过使用 NSAttributedStrings 并寻找你的文本范围来变得更干净..

let myText = NSMutableAttributedString(string: textView.text, attributes: normalAttributes)

// this will only turn up the FIRST occurrence
if let range = myText.range(of: selectedWord) {
    let rangeOfSelected = NSRange(range, in: myText)
    myText.setAttributes(selectedAttributes, range: rangeOfSelected)
}

如果您想使用任意事件,您可以写一个扩展来创建一个包含所有范围的数组,然后选择重要的一个,这是一个很好的引用:https://medium.com/@weijentu/find-and-return-the-ranges-of-all-the-occurrences-of-a-given-string-in-swift-2a2015907a0e

不过,Def 可能有点矫枉过正,您也可以修改那些文章中的方法,改为采用 int (occuranceNumber) 并使用像上面这样的计数器来仅返回第 n 次出现的范围,然后对属性字符串执行相同的操作。

关于ios - 如何为 UITextView 中的特定单词设置样式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59182861/

相关文章:

ios - Objective-C 编译器遗漏了协议(protocol)定义

iphone - iPhone Voip中的扬声器电话功能

ios - 正在进行 WebRTC 音频通话时,AVAudioPlayer 以非常低的音量播放声音

swift - 获取语​​言环境日期格式信息

javascript - 如何从 XMLHttpRequest 响应中获取 <p> 标签值并在 html 中设置

objective-c - 如何判断 UIWebView 何时完成显示内容

ios - 根据其框架大小设置 UILabel 字体大小?

ios - 为什么登录时未调用 "ASAuthorizationControllerDelegate"?

python - 如何从仅包含键列表和键值对的列表创建字典(Python)?

c++ - 将非 null 终止的 vector<char> 转换为字符串