【问题标题】:Making text bold using attributed string in swift在swift中使用属性字符串使文本变为粗体
【发布时间】:2015-04-14 06:54:42
【问题描述】:

我有一个这样的字符串

var str = "@text1 this is good @text1"

现在将text1 替换为另一个字符串,例如t 1。我可以替换文本,但我无法将其加粗。我想将新字符串t 1加粗,这样最终的输出就是:

@t 1 这很好@t 1

我该怎么做?

我看到的所有示例都在 Objective-C 中,但我想在 Swift 中完成。

提前致谢。

【问题讨论】:

标签: ios swift nsmutableattributedstring


【解决方案1】:

编辑/更新:Xcode 13.1 • Swift 5.5.1

如果您了解 HTML 和 CSS,您可以使用它轻松控制属性字符串的字体样式、颜色和大小,如下所示:

讨论
不应从后台线程调用 HTML 导入器(即,选项字典包含值为 html 的 documentType)。它将尝试与主线程同步,失败并超时。从主线程调用它是可行的(但如果 HTML 包含对外部资源的引用,仍然会超时,应该不惜一切代价避免这种情况)。 HTML 导入机制旨在实现诸如 markdown 之类的东西(即文本样式、颜色等),而不是用于一般的 HTML 导入。


extension StringProtocol {
    var html2AttStr: NSAttributedString? {
        try? NSAttributedString(data: Data(utf8), options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)

    }
}

"<style type=\"text/css\">#red{color:#F00}#green{color:#0F0}#blue{color: #00F; font-weight: Bold; font-size: 32}</style><span id=\"red\" >Red,</span><span id=\"green\" > Green </span><span id=\"blue\">and Blue</span>".html2AttStr

【讨论】:

  • 我正在尝试在 Swift 2 Xcode 中实现这一点,但没有应用字体。这是字符串:&lt;link href=\"https://fonts.googleapis.com/css?family=Frank+Ruhl+Libre\" rel=\"stylesheet\"&gt; &lt;span style=\"font-family: 'Frank Ruhl Libre', sans-serif;\"&gt;שלום&lt;/span&gt;
  • 如果它使用 WebKit 来解析 NSAttributedString 中的 HTML 字符串,请小心在后台线程中使用它...
  • 使用这种方法而不是@prajeet answer有什么好处?
  • @EmreÖnder 这只是个人喜好。如果你知道 html,那么简单地使用上面的扩展会更容易。
【解决方案2】:
var normalText = "Hi am normal"

var boldText  = "And I am BOLD!"

var attributedString = NSMutableAttributedString(string:normalText)

var attrs = [NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 15)]
var boldString = NSMutableAttributedString(string: boldText, attributes:attrs)

attributedString.append(boldString)

当您想将其分配给标签时:

yourLabel.attributedText = attributedString

【讨论】:

  • 很棒的答案!谢谢!
  • 注意:appendAttributedString 已重命名为 .append()
【解决方案3】:

用法:

let label = UILabel()
label.attributedText =
    NSMutableAttributedString()
        .bold("Address: ")
        .normal(" Kathmandu, Nepal\n\n")
        .orangeHighlight(" Email: ")
        .blackHighlight(" prajeet.shrestha@gmail.com ")
        .bold("\n\nCopyright: ")
        .underlined(" All rights reserved. 2020.")

结果:

这是一种在单个标签中组合粗体和普通文本以及其他一些奖励方法的巧妙方法。

扩展:Swift 5.*

extension NSMutableAttributedString {
    var fontSize:CGFloat { return 14 }
    var boldFont:UIFont { return UIFont(name: "AvenirNext-Bold", size: fontSize) ?? UIFont.boldSystemFont(ofSize: fontSize) }
    var normalFont:UIFont { return UIFont(name: "AvenirNext-Regular", size: fontSize) ?? UIFont.systemFont(ofSize: fontSize)}
    
    func bold(_ value:String) -> NSMutableAttributedString {
        
        let attributes:[NSAttributedString.Key : Any] = [
            .font : boldFont
        ]
        
        self.append(NSAttributedString(string: value, attributes:attributes))
        return self
    }
    
    func normal(_ value:String) -> NSMutableAttributedString {
        
        let attributes:[NSAttributedString.Key : Any] = [
            .font : normalFont,
        ]
        
        self.append(NSAttributedString(string: value, attributes:attributes))
        return self
    }
    /* Other styling methods */
    func orangeHighlight(_ value:String) -> NSMutableAttributedString {
        
        let attributes:[NSAttributedString.Key : Any] = [
            .font :  normalFont,
            .foregroundColor : UIColor.white,
            .backgroundColor : UIColor.orange
        ]
        
        self.append(NSAttributedString(string: value, attributes:attributes))
        return self
    }
    
    func blackHighlight(_ value:String) -> NSMutableAttributedString {
        
        let attributes:[NSAttributedString.Key : Any] = [
            .font :  normalFont,
            .foregroundColor : UIColor.white,
            .backgroundColor : UIColor.black
            
        ]
        
        self.append(NSAttributedString(string: value, attributes:attributes))
        return self
    }
    
    func underlined(_ value:String) -> NSMutableAttributedString {
        
        let attributes:[NSAttributedString.Key : Any] = [
            .font :  normalFont,
            .underlineStyle : NSUnderlineStyle.single.rawValue
            
        ]
        
        self.append(NSAttributedString(string: value, attributes:attributes))
        return self
    }
}

注意:如果编译器缺少 UIFont/UIColor,请将其替换为 NSFont/NSColor。

【讨论】:

  • 不是 swift 2 的吗?
  • 一个小补充:func bold(_ text:String, _ size:CGFloat)。我在粗体上加了大小,这样我就可以从外面控制它。另外,我错过了这个函数中的AvenirNext-Medium 字体,所以我花了几分钟才明白为什么我看不到我的字体。请注意。
  • 你拯救了我的一天,伙计!
  • 谢谢!像魅力一样工作:)
  • 巴莱巴莱萨卡尔:D
【解决方案4】:

Swift 4 及更高版本

对于 Swift 4 及更高版本,这是一个好方法:

    let attributsBold = [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16, weight: .bold)]
    let attributsNormal = [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16, weight: .regular)]
    var attributedString = NSMutableAttributedString(string: "Hi ", attributes:attributsNormal)
    let boldStringPart = NSMutableAttributedString(string: "John", attributes:attributsBold)
    attributedString.append(boldStringPart)
  
    yourLabel.attributedText = attributedString

在标签中,文本看起来像:“Hi John

【讨论】:

    【解决方案5】:

    For -> 按尺寸搜索电视

    1-way 使用 NString 及其范围

    let query = "Television"
    let headerTitle = "size"
    let message = "Search \(query) by \(headerTitle)"
    let range = (message as NSString).range(of: query)
    let attributedString = NSMutableAttributedString(string: message)
    attributedString.addAttribute(NSAttributedString.Key.font, value: UIFont.boldSystemFont(ofSize: label1.font.pointSize), range: range)
    label1.attributedText = attributedString
    

    另一个没有使用 NString 及其范围

    let query = "Television"
    let headerTitle = "size"
    let (searchText, byText) = ("Search ", " by \(headerTitle)")
    let attributedString = NSMutableAttributedString(string: searchText)
    let byTextAttributedString = NSMutableAttributedString(string: byText)
    let attrs = [NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: label1.font.pointSize)]
    let boldString = NSMutableAttributedString(string: query, attributes:attrs)
    attributedString.append(boldString)
    attributedString.append(byTextAttributedString)
    label1.attributedText = attributedString
    

    swift5

    【讨论】:

      【解决方案6】:

      斯威夫特 5.1 使用NSAttributedString.Key 而不是NSAttributedStringKey

      let test1Attributes:[NSAttributedString.Key: Any] = [.font : UIFont(name: "CircularStd-Book", size: 14)!]
      let test2Attributes:[NSAttributedString.Key: Any] = [.font : UIFont(name: "CircularStd-Bold", size: 16)!]
      
      let test1 = NSAttributedString(string: "\(greeting!) ", attributes:test1Attributes)
      let test2 = NSAttributedString(string: firstName!, attributes:test2Attributes)
      let text = NSMutableAttributedString()
      
      text.append(test1)
      text.append(test2)
      return text
      

      【讨论】:

        【解决方案7】:

        swift 4 中的两个班轮:

                    button.setAttributedTitle(.init(string: "My text", attributes: [.font: UIFont.systemFont(ofSize: 20, weight: .bold)]), for: .selected)
                    button.setAttributedTitle(.init(string: "My text", attributes: [.font: UIFont.systemFont(ofSize: 20, weight: .regular)]), for: .normal)
        

        【讨论】:

          【解决方案8】:

          您可以使用下面编写的简单自定义方法来执行此操作。 您在第一个参数中给出了整个字符串,在第二个参数中给出了粗体字。希望这会有所帮助。

          func getAttributedBoldString(str : String, boldTxt : String) -> NSMutableAttributedString {
                  let attrStr = NSMutableAttributedString.init(string: str)
                  let boldedRange = NSRange(str.range(of: boldTxt)!, in: str)
                  attrStr.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 17, weight: .bold)], range: boldedRange)
                  return attrStr
              }
          

          用法: initalString = 我是男孩

          label.attributedText = getAttributedBoldString(str : initalString, boldTxt : "Boy")

          结果字符串 = 我是一个男孩

          【讨论】:

            【解决方案9】:

            用法....

            let attrString = NSMutableAttributedString()
                        .appendWith(weight: .semibold, "almost bold")
                        .appendWith(color: .white, weight: .bold, " white and bold")
                        .appendWith(color: .black, ofSize: 18.0, " big black")
            

            两美分...

            extension NSMutableAttributedString {
            
                @discardableResult func appendWith(color: UIColor = UIColor.darkText, weight: UIFont.Weight = .regular, ofSize: CGFloat = 12.0, _ text: String) -> NSMutableAttributedString{
                    let attrText = NSAttributedString.makeWith(color: color, weight: weight, ofSize:ofSize, text)
                    self.append(attrText)
                    return self
                }
            
            }
            extension NSAttributedString {
            
                public static func makeWith(color: UIColor = UIColor.darkText, weight: UIFont.Weight = .regular, ofSize: CGFloat = 12.0, _ text: String) -> NSMutableAttributedString {
            
                    let attrs = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: ofSize, weight: weight), NSAttributedStringKey.foregroundColor: color]
                    return NSMutableAttributedString(string: text, attributes:attrs)
                }
            }
            

            【讨论】:

            • iOS 11 或更高版本(由于 UIFont.Weight 的使用)。
            【解决方案10】:

            只需使用类似这样的代码:

             let font = UIFont(name: "Your-Font-Name", size: 10.0)!
            
                    let attributedText = NSMutableAttributedString(attributedString: noteLabel.attributedText!)
                    let boldedRange = NSRange(attributedText.string.range(of: "Note:")!, in: attributedText.string)
                    attributedText.addAttributes([NSAttributedString.Key.font : font], range: boldedRange)
                    noteLabel.attributedText = attributedText
            

            【讨论】:

              【解决方案11】:

              超级简单的方法。

                  let text = "This string is having multiple font"
                  let attributedText = 
                  NSMutableAttributedString.getAttributedString(fromString: text)
              
                  attributedText.apply(font: UIFont.boldSystemFont(ofSize: 24), subString: 
                  "This")
              
                  attributedText.apply(font: UIFont.boldSystemFont(ofSize: 24), onRange: 
                  NSMakeRange(5, 6))
              

              更多详情请点击这里: https://github.com/iOSTechHub/AttributedString

              【讨论】:

              • 半粗体怎么样?
              • 这应该是公认的答案。 @Houman 使用上面的库并将apply 方法与您想要的字体一起使用
              【解决方案12】:

              在此线程中接受Prajeet Shrestha 的响应为有效,如果已知标签和字体特征,我想使用标签扩展他的解决方案。

              斯威夫特 4

              extension NSMutableAttributedString {
              
                  @discardableResult func normal(_ text: String) -> NSMutableAttributedString {
                      let normal = NSAttributedString(string: text)
                      append(normal)
              
                      return self
                  }
              
                  @discardableResult func bold(_ text: String, withLabel label: UILabel) -> NSMutableAttributedString {
              
                      //generate the bold font
                      var font: UIFont = UIFont(name: label.font.fontName , size: label.font.pointSize)!
                      font = UIFont(descriptor: font.fontDescriptor.withSymbolicTraits(.traitBold) ?? font.fontDescriptor, size: font.pointSize)
              
                      //generate attributes
                      let attrs: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: font]
                      let boldString = NSMutableAttributedString(string:text, attributes: attrs)
              
                      //append the attributed text
                      append(boldString)
              
                      return self
                  }
              }
              

              【讨论】:

                【解决方案13】:

                斯威夫特 3.0

                根据您的要求将 html 转换为字符串和字体更改。

                do {
                
                     let str = try NSAttributedString(data: ("I'm a normal text and <b>this is my bold part . </b>And I'm again in the normal text".data(using: String.Encoding.unicode, allowLossyConversion: true)!), options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
                
                     myLabel.attributedText = str
                     myLabel.font =  MONTSERRAT_BOLD(23)
                     myLabel.textAlignment = NSTextAlignment.left
                } catch {
                     print(error)
                }
                


                func MONTSERRAT_BOLD(_ size: CGFloat) -> UIFont
                {
                    return UIFont(name: "MONTSERRAT-BOLD", size: size)!
                }
                

                【讨论】:

                • 您应该使用 utf8 将您的字符串转换为数据。请注意,Data 符合 Swift 3 中的集合,因此您可以使用字符串 utf8 集合视图 Data("I'm a normal text and &lt;b&gt;this is my bold part . &lt;/b&gt;And I'm again in the normal text".utf8) 初始化 Data 并在选项 [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue] 中设置字符编码
                【解决方案14】:

                改进 Prajeet Shrestha 答案:-

                您可以为 NSMutableAttributedString 创建一个通用扩展,这涉及更少的代码。在这种情况下,我选择使用系统字体,但您可以对其进行调整,以便输入字体名称作为参数。

                    extension NSMutableAttributedString {
                
                        func systemFontWith(text: String, size: CGFloat, weight: CGFloat) -> NSMutableAttributedString {
                            let attributes: [String: AnyObject] = [NSFontAttributeName: UIFont.systemFont(ofSize: size, weight: weight)]
                            let string = NSMutableAttributedString(string: text, attributes: attributes)
                            self.append(string)
                            return self
                        }
                    }
                

                【讨论】:

                  【解决方案15】:

                  基于 Jeremy Bader 和 David West 的出色答案,Swift 3 扩展:

                  extension String {
                      func withBoldText(boldPartsOfString: Array<NSString>, font: UIFont!, boldFont: UIFont!) -> NSAttributedString {
                          let nonBoldFontAttribute = [NSFontAttributeName:font!]
                          let boldFontAttribute = [NSFontAttributeName:boldFont!]
                          let boldString = NSMutableAttributedString(string: self as String, attributes:nonBoldFontAttribute)
                          for i in 0 ..< boldPartsOfString.count {
                              boldString.addAttributes(boldFontAttribute, range: (self as NSString).range(of: boldPartsOfString[i] as String))
                          }
                          return boldString
                      }
                  }
                  

                  用法:

                  let label = UILabel()
                  let font = UIFont(name: "AvenirNext-Italic", size: 24)!
                  let boldFont = UIFont(name: "AvenirNext-BoldItalic", size: 24)!
                  label.attributedText = "Make sure your face is\nbrightly and evenly lit".withBoldText(
                      boldPartsOfString: ["brightly", "evenly"], font: font, boldFont: boldFont)
                  

                  【讨论】:

                    【解决方案16】:

                    我扩展了 David West 的精彩答案,以便您可以输入一个字符串并告诉它所有您想要加粗的子字符串:

                    func addBoldText(fullString: NSString, boldPartsOfString: Array<NSString>, font: UIFont!, boldFont: UIFont!) -> NSAttributedString {
                        let nonBoldFontAttribute = [NSFontAttributeName:font!]
                        let boldFontAttribute = [NSFontAttributeName:boldFont!]
                        let boldString = NSMutableAttributedString(string: fullString as String, attributes:nonBoldFontAttribute)
                        for i in 0 ..< boldPartsOfString.count {
                            boldString.addAttributes(boldFontAttribute, range: fullString.rangeOfString(boldPartsOfString[i] as String))
                        }
                        return boldString
                    }
                    

                    然后这样称呼它:

                    let normalFont = UIFont(name: "Dosis-Medium", size: 18)
                    let boldSearchFont = UIFont(name: "Dosis-Bold", size: 18)
                    self.UILabel.attributedText = addBoldText("Check again in 30 days to find more friends", boldPartsOfString: ["Check", "30 days", "find", "friends"], font: normalFont!, boldFont: boldSearchFont!)
                    

                    这将使您想要在给定字符串中加粗的所有子字符串加粗

                    【讨论】:

                    • 是否可以在两个不同的地方使用相同的单词粗体?例如:“30 天后再次查看,找到 30 个朋友”。你如何使两个“30”都加粗?提前致谢。
                    【解决方案17】:

                    如果您使用的是本地化字符串,您可能无法依赖始终位于句子末尾的粗体字符串。如果是这种情况,那么以下方法效果很好:

                    例如查询“blah”不匹配任何项目

                    /* Create the search query part of the text, e.g. "blah". 
                       The variable 'text' is just the value entered by  the user. */
                    let searchQuery = "\"\(text)\""
                    
                    /* Put the search text into the message */
                    let message = "Query \(searchQuery). does not match any items"
                    
                    /* Find the position of the search string. Cast to NSString as we want
                       range to be of type NSRange, not Swift's Range<Index> */
                    let range = (message as NSString).rangeOfString(searchQuery)
                    
                    /* Make the text at the given range bold. Rather than hard-coding a text size,
                       Use the text size configured in Interface Builder. */
                    let attributedString = NSMutableAttributedString(string: message)
                    attributedString.addAttribute(NSFontAttributeName, value: UIFont.boldSystemFontOfSize(label.font.pointSize), range: range)
                    
                    /* Put the text in a label */
                    label.attributedText = attributedString
                    

                    【讨论】:

                    • 经过数小时的搜索,这是找到解决我问题的唯一答案。 +1
                    • @Super_Simon 对我来说也一样,很多答案都是直接添加文本,这对本地化字符串不起作用。
                    【解决方案18】:

                    这是我想出的最好的方法。添加一个您可以从任何地方调用的函数,并将其添加到一个没有像 Constants.swift 这样的类的文件中,然后您可以在许多情况下通过调用 ONE LINE 代码来使任何字符串中的单词加粗:

                    进入一个 constants.swift 文件:

                    import Foundation
                    import UIKit
                    
                    func addBoldText(fullString: NSString, boldPartOfString: NSString, font: UIFont!, boldFont: UIFont!) -> NSAttributedString {
                       let nonBoldFontAttribute = [NSFontAttributeName:font!]
                       let boldFontAttribute = [NSFontAttributeName:boldFont!]
                       let boldString = NSMutableAttributedString(string: fullString as String, attributes:nonBoldFontAttribute)
                       boldString.addAttributes(boldFontAttribute, range: fullString.rangeOfString(boldPartOfString as String))
                       return boldString
                    }
                    

                    然后你可以为任何 UILabel 调用这行代码:

                    self.UILabel.attributedText = addBoldText("Check again in 30 DAYS to find more friends", boldPartOfString: "30 DAYS", font: normalFont!, boldFont: boldSearchFont!)
                    
                    
                    //Mark: Albeit that you've had to define these somewhere:
                    
                    let normalFont = UIFont(name: "INSERT FONT NAME", size: 15)
                    let boldFont = UIFont(name: "INSERT BOLD FONT", size: 15)
                    

                    【讨论】:

                      【解决方案19】:

                      这可能很有用

                      class func createAttributedStringFrom (string1 : String ,strin2 : String, attributes1 : Dictionary<String, NSObject>, attributes2 : Dictionary<String, NSObject>) -> NSAttributedString{
                      
                      let fullStringNormal = (string1 + strin2) as NSString
                      let attributedFullString = NSMutableAttributedString(string: fullStringNormal as String)
                      
                      attributedFullString.addAttributes(attributes1, range: fullStringNormal.rangeOfString(string1))
                      attributedFullString.addAttributes(attributes2, range: fullStringNormal.rangeOfString(strin2))
                      return attributedFullString
                      }
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2012-04-05
                        • 2018-05-22
                        • 2014-09-02
                        • 1970-01-01
                        • 1970-01-01
                        • 2016-05-14
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多