【问题标题】:How to format attributed strings in swift?如何快速格式化属性字符串?
【发布时间】:2017-09-26 18:29:45
【问题描述】:

我正在处理一个通知页面,其中输入主要来自 JSON 文件,我需要将它们与本地化字符串结合起来。它应该是这样的:

可以预测,彩色部分来自 JSON 文件,其余部分来自 Localizable.strings。这是来自 Localizable 文件的内容:

"%@ has joined %@"

如果我使用String(format: String, [...]),我有一个纯黑色文本,我无法指定需要着色的部分。

NSAttributedString 我需要同样的功能,但它没有这个方法。

那么如何格式化属性字符串呢?

【问题讨论】:

  • 这取决于你想应用什么样的效果,但最简单的方法是在本地化的值上使用 HTML 标签。
  • @Larme 我想改变颜色并使格式化部分加粗,查看示例截图。 UILabel 会自动应用 HTML 标签吗?
  • 我检查了样本,但您可能想要更多效果。您可以从 HTML 文本中初始化 NSAttributedString(所有标签均未翻译,但仅管理粗体/颜色):stackoverflow.com/questions/39248092/… 因此添加 <b> 和其他人应该可以解决问题。

标签: ios iphone swift string nsattributedstring


【解决方案1】:

查看以下示例:

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

或其他方式:

要更改一段文本的颜色,您需要知道字符串中已着色字符的开始和结束索引,例如

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

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

然后您转换为属性字符串并使用“添加属性”和NSForegroundColorAttributeName

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

【讨论】:

  • rangeOfString() 仅返回第一个范围。如果占位符的两个值("%@ has joined %@")相同,则不起作用。
  • rangeOfString 自 Swift 3 起已重命名为 range(of: String)
  • 如果您使用“$1, $2”来放置物品也会出现问题(并非所有语言都保持相同的顺序)。这就是为什么在我的项目中我使用 HTML 标签。但这比什么都重要。您的解决方案可能会奏效。
【解决方案2】:

试试下面的代码并相应地更新你的逻辑。

    let localizableStr = "%@ has joined %@"
    let localisedStr = NSLocalizedString(localizableStr, comment: "")

    let components = localizableStr.components(separatedBy: "%@")

    let formatterStr = components.count > 2 ? components[1] : "has joined"

    let evaluatedStr = NSString(format: localisedStr as NSString, "Rishi ", "Stack OVerflow")

    let attributedStr = NSMutableAttributedString(string: evaluatedStr as String)
    attributedStr.addAttribute(NSForegroundColorAttributeName, value: UIColor.brown, range: NSMakeRange(0, attributedStr.length))

    let formatterStrRange = evaluatedStr.range(of: formatterStr, options: .caseInsensitive)
    attributedStr.addAttribute(NSForegroundColorAttributeName, value: UIColor.black, range: formatterStrRange)

【讨论】:

    【解决方案3】:

    我的两个本地化字符串:

    "welcome message" = "%@ has joined %@";
    "welcome message" = "انضم %@ إلى %@";
    

    结果

    
    extension String {
    
     func localisedAttributedString(_ replacements: CVarArg..., attributes: [NSAttributedString.Key : Any], replacementAttributes: [[NSAttributedString.Key : Any]?] ) -> NSAttributedString {
            
    
            let message = String.init(format: NSLocalizedString(self, comment: ""), arguments: replacements)
            
            let attributedString =  NSMutableAttributedString(string: message, attributes: attributes)
           
            
            for (i, replacement) in replacements.enumerated() {
                
                if let att = replacementAttributes[i] {
                    
                    let range = (attributedString.string.range(of: "\(replacement)".localized)?.nsRange(in: attributedString.string)) ?? NSRange(location: 0, length: 0)
                    attributedString.addAttributes(att as [NSAttributedString.Key : Any], range: range)
                }
                
            }
            
            return attributedString
        }
    
    }
    

    如何使用

    //General attr: Applied to the entire string
    let generalAttributes = [NSAttributedString.Key.font:  UIFont.getFont(.regular, size: 20)]
    
    
    //Additional attrs applied to the replacement / dynamic bits. You can pass nil too
    let nameAttributes = [ NSAttributedString.Key.backgroundColor: UIColor.red]
    let companyAttributes = [ NSAttributedString.Key.foregroundColor: UIColor.blue]
            
    myLabel.attributedText = "welcome message".localisedAttributedString("adam".localized, "space".localized, attributes: generalAttributes, replacementAttributes: [nameAttributes, companyAttributes] )
    
    

    【讨论】:

      猜你喜欢
      • 2011-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-14
      相关资源
      最近更新 更多