【问题标题】:How to Increase Line spacing in UILabel in Swift如何在 Swift 中增加 UILabel 中的行距
【发布时间】:2017-01-02 16:08:08
【问题描述】:

我有一个只有几行文本的标签,我想增加行间距。其他人也提出了类似的问题,但解决方案并不能解决我的问题。我的标签也可能包含也可能不包含段落。我是Swift 的新手。有没有使用故事板的解决方案?还是只能通过NSAttributedString 可能?

【问题讨论】:

    标签: ios swift uilabel line-spacing


    【解决方案1】:

    此解决方案适用于 swift 5 这是对https://stackoverflow.com/a/62116213/13171606的回答的参考

    我对“NSMutableAttributedString”做了一些更改,并包含了完整的示例,我认为它会对大家有所帮助

    注意:如果发现错误请调整颜色和字体样式。

    扩展

    extension NSAttributedString {
        func withLineSpacing(_ spacing: CGFloat) -> NSMutableAttributedString {
                let attributedString = NSMutableAttributedString(attributedString: self)
                let paragraphStyle = NSMutableParagraphStyle()
                paragraphStyle.lineBreakMode = .byTruncatingTail
                paragraphStyle.lineSpacing = spacing
                attributedString.addAttribute(.paragraphStyle,
                                      value: paragraphStyle,
                                      range: NSRange(location: 0, length: string.count))
                return NSMutableAttributedString(attributedString: attributedString)
        }
    }
    

    实施示例

    let myAttributedText = NSMutableAttributedString(string: "Please enter the required details to change your AAAAAAAAA AAAAA AAAAA. Maximum AAAAA can be AAA AA AAA AA.\n\nNote: If you do not have a AAAAA AAAA then please AAAAAAA us at 111-111-111 or send us an email AAAA AAAA AAA AAAAAAAAAA AAAAA address at xxxxxxxxxxxxxxxxxxxxxxxxxxxx.", attributes: [
            .font: UIFont.systemFont(ofSize: 14),
            .foregroundColor: UIColor.gray,
            .kern: 0.0]).withLineSpacing(8)
        myAttributedText.addAttributes([
            .font: UIFont.systemFont(ofSize: 14),
            .foregroundColor: UIColor.blue],
                                       range: NSRange(location: 174, length: 11))
        myAttributedText.addAttributes([
            .font: UIFont.systemFont(ofSize: 14),
            .foregroundColor: UIColor.blue],
                                       range: NSRange(location: 248, length: 28))
    

    UILable

    let myLabel: UILabel = {
       let label = UILabel()
       label.textAlignment = .left
       label.numberOfLines = 0
       label.attributedText = myAttributedText //Here is your Attributed String
       return label
    }() 
    

    【讨论】:

      【解决方案2】:

      Swift 4 和 Swift 5

      extension NSAttributedString {
          func withLineSpacing(_ spacing: CGFloat) -> NSAttributedString {
              let attributedString = NSMutableAttributedString(attributedString: self)
              let paragraphStyle = NSMutableParagraphStyle()
              paragraphStyle.lineBreakMode = .byTruncatingTail
              paragraphStyle.lineSpacing = spacing
              attributedString.addAttribute(.paragraphStyle,
                                            value: paragraphStyle,
                                            range: NSRange(location: 0, length: string.count))
              return NSAttributedString(attributedString: attributedString)
          }
      }
      

      如何使用

          let example = NSAttributedString(string: "This is Line 1 \nLine 2 \nLine 3 ").withLineSpacing(15)
          testLabel.attributedText = example
      

      【讨论】:

        【解决方案3】:

        创建标签样式

        struct LabelStyle {
            
                let font: UIFont
                let fontMetrics: UIFontMetrics?
                let lineHeight: CGFloat?
                let tracking: CGFloat
                
                init(font: UIFont, fontMetrics: UIFontMetrics? = nil, lineHeight: CGFloat? = nil, tracking: CGFloat = 0) {
                    self.font = font
                    self.fontMetrics = fontMetrics
                    self.lineHeight = lineHeight
                    self.tracking = tracking
                }
                
                func attributes(for alignment: NSTextAlignment, lineBreakMode: NSLineBreakMode) -> [NSAttributedString.Key: Any] {
                    
                    let paragraphStyle = NSMutableParagraphStyle()
                    paragraphStyle.alignment = alignment
                    paragraphStyle.lineBreakMode = lineBreakMode
                    
                    var baselineOffset: CGFloat = .zero
                    
                    if let lineHeight = lineHeight {
                        let lineHeightMultiple = lineHeight / font.lineHeight
                        paragraphStyle.lineHeightMultiple = lineHeightMultiple
                        
                        baselineOffset = 1 / lineHeightMultiple
                        
                        let scaledLineHeight: CGFloat = fontMetrics?.scaledValue(for: lineHeight) ?? lineHeight
                        paragraphStyle.minimumLineHeight = scaledLineHeight
                        paragraphStyle.maximumLineHeight = scaledLineHeight
                    }
                    
                    return [
                        NSAttributedString.Key.paragraphStyle: paragraphStyle,
                        NSAttributedString.Key.kern: tracking,
                        NSAttributedString.Key.baselineOffset: baselineOffset,
                        NSAttributedString.Key.font: font
                    ]
                }
            }
        

        创建自定义标签类并使用我们的样式

        public class Label: UILabel {
          
          var style: LabelStyle? { nil }
          
          public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
            super.traitCollectionDidChange(previousTraitCollection)
            
            if previousTraitCollection?.preferredContentSizeCategory != traitCollection.preferredContentSizeCategory {
              updateText()
            }
          }
          
          convenience init(text: String?, textColor: UIColor) {
            self.init()
            self.text = text
            self.textColor = textColor
          }
          
          override init(frame: CGRect) {
            super.init(frame: frame)
            commonInit()
          }
          
          required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            commonInit()
            updateText()
          }
          
          private func commonInit() {
            font = style?.font
            adjustsFontForContentSizeCategory = true
          }
          
          private func updateText() {
            text = super.text
          }
          
          public override var text: String? {
            get {
              guard style?.attributes != nil else {
                return super.text
              }
              
              return attributedText?.string
            }
            set {
              guard let style = style else {
                super.text = newValue
                return
              }
              
              guard let newText = newValue else {
                attributedText = nil
                super.text = nil
                return
              }
              
              let attributes = style.attributes(for: textAlignment, lineBreakMode: lineBreakMode)
              attributedText = NSAttributedString(string: newText, attributes: attributes)
            }
          }
        }
        

        创建具体标签

        public final class TitleLabel {
        
            override var style: LabelStyle? {
                LabelStyle(
                    font: UIFont.Title(),
                    lineHeight: 26.21,
                    tracking: 0.14
                )
            }
        }
        

        并使用它

        @IBOutlet weak var titleLabel: TitleLabel!
        

        【讨论】:

          【解决方案4】:

          除了使用属性字符串和段落样式,对于小的调整,字体描述符也可以派上用场。

          例如:

          let font: UIFont = .init(
              descriptor: UIFontDescriptor
                  .preferredFontDescriptor(withTextStyle: .body)
                  .withSymbolicTraits(.traitLooseLeading)!,
              size: 0
          )
          

          这将创建一个前导较松的字体,导致文本的行高比默认系统字体稍大(它增加了 2 个点)。 traitTightLeading 也可以用于相反的效果(它将字体的前导减少 2 点)。

          我在这里写了一篇比较这些方法的博文:https://bootstragram.com/blog/line-height-with-uikit/。

          【讨论】:

            【解决方案5】:
            extension UILabel {
                var spasing:CGFloat {
                    get {return 0}
                    set {
                        let textAlignment = self.textAlignment
                        let paragraphStyle = NSMutableParagraphStyle()
                        paragraphStyle.lineSpacing = newValue
                        let attributedString = NSAttributedString(string: self.text ?? "", attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])
                        self.attributedText = attributedString
                        self.textAlignment = textAlignment
                    }
                }
            }
            
            
            let label = UILabel()
            label.text = "test"
            label.spasing = 10
            

            【讨论】:

              【解决方案6】:

              Swift 5.0 的最新解决方案

              private extension UILabel {
              
                  // MARK: - spacingValue is spacing that you need
                  func addInterlineSpacing(spacingValue: CGFloat = 2) {
              
                      // MARK: - Check if there's any text
                      guard let textString = text else { return }
              
                      // MARK: - Create "NSMutableAttributedString" with your text
                      let attributedString = NSMutableAttributedString(string: textString)
              
                      // MARK: - Create instance of "NSMutableParagraphStyle"
                      let paragraphStyle = NSMutableParagraphStyle()
              
                      // MARK: - Actually adding spacing we need to ParagraphStyle
                      paragraphStyle.lineSpacing = spacingValue
              
                      // MARK: - Adding ParagraphStyle to your attributed String
                      attributedString.addAttribute(
                          .paragraphStyle,
                          value: paragraphStyle,
                          range: NSRange(location: 0, length: attributedString.length
                      ))
              
                      // MARK: - Assign string that you've modified to current attributed Text
                      attributedText = attributedString
                  }
              
              }
              

              及用法:

              let yourLabel = UILabel()
              let yourText = "Hello \n world \n !"
              yourLabel.text = yourText
              yourLabel.addInterlineSpacing(spacingValue: 1.5)
              

              【讨论】:

              • 这当然只有在你使用UILabel.text而不是UILabel.attributedText时才有效
              【解决方案7】:

              您可以使用这个可重复使用的扩展:

              extension String {
              
              func lineSpaced(_ spacing: CGFloat) -> NSAttributedString {
                  let paragraphStyle = NSMutableParagraphStyle()
                  paragraphStyle.lineSpacing = spacing
                  let attributedString = NSAttributedString(string: self, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])
                  return attributedString
              }
              }
              

              【讨论】:

                【解决方案8】:

                使用以下 sn-p 以编程方式将 LineSpacing 添加到您的 UILabel。

                早期的 Swift 版本

                let attributedString = NSMutableAttributedString(string: "Your text")
                
                // *** Create instance of `NSMutableParagraphStyle`
                let paragraphStyle = NSMutableParagraphStyle()
                
                // *** set LineSpacing property in points ***
                paragraphStyle.lineSpacing = 2 // Whatever line spacing you want in points
                
                // *** Apply attribute to string ***
                attributedString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
                
                // *** Set Attributed String to your label ***
                label.attributedText = attributedString
                

                Swift 4.0

                let attributedString = NSMutableAttributedString(string: "Your text")
                
                // *** Create instance of `NSMutableParagraphStyle`
                let paragraphStyle = NSMutableParagraphStyle()
                
                // *** set LineSpacing property in points ***
                paragraphStyle.lineSpacing = 2 // Whatever line spacing you want in points
                
                // *** Apply attribute to string ***
                attributedString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
                
                // *** Set Attributed String to your label ***
                label.attributedText = attributedString
                

                斯威夫特 4.2

                let attributedString = NSMutableAttributedString(string: "Your text")
                
                // *** Create instance of `NSMutableParagraphStyle`
                let paragraphStyle = NSMutableParagraphStyle()
                
                // *** set LineSpacing property in points ***
                paragraphStyle.lineSpacing = 2 // Whatever line spacing you want in points
                
                // *** Apply attribute to string ***
                attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
                
                // *** Set Attributed String to your label ***
                label.attributedText = attributedString
                

                【讨论】:

                • 这显示错误“'NSAttributedString' 类型的值没有成员'addAttribute'”。
                • 我们需要使用NSMutableAttributedString 而不是NSAttributedString。我已经更新了。
                • 使用自定义字体也很棒@Dipen Panchasara
                • 我不知道为什么,但对我来说,这只有在你设置行距> = 1时才有效,我试图设置 0.5 / 0.75,它没有效果
                • 不需要NSMutableAttributedString。可以使用NSAttributedString(string: "Your text", attributes: [NSAttributedString.Key.paragraphStyle : paragraphStyle])
                【解决方案9】:
                //Swift 4:
                    func set(text:String,
                                         inLabel:UILabel,
                                         withLineSpacing:CGFloat,
                                         alignment:NSTextAlignment){
                            let paragraphStyle = NSMutableParagraphStyle()
                            paragraphStyle.lineSpacing = withLineSpacing
                            let attrString = NSMutableAttributedString(string: text)
                            attrString.addAttribute(NSAttributedStringKey.paragraphStyle,
                                                    value:paragraphStyle,
                                                    range:NSMakeRange(0, attrString.length))
                            inLabel.attributedText = attrString
                            inLabel.textAlignment = alignment
                          }
                

                【讨论】:

                  【解决方案10】:

                  来自界面生成器:

                  以编程方式:

                  SWift 4 和 4.2

                  使用标签扩展

                  extension UILabel {
                  
                      func setLineSpacing(lineSpacing: CGFloat = 0.0, lineHeightMultiple: CGFloat = 0.0) {
                  
                          guard let labelText = self.text else { return }
                  
                          let paragraphStyle = NSMutableParagraphStyle()
                          paragraphStyle.lineSpacing = lineSpacing
                          paragraphStyle.lineHeightMultiple = lineHeightMultiple
                  
                          let attributedString:NSMutableAttributedString
                          if let labelattributedText = self.attributedText {
                              attributedString = NSMutableAttributedString(attributedString: labelattributedText)
                          } else {
                              attributedString = NSMutableAttributedString(string: labelText)
                          }
                  
                          // (Swift 4.2 and above) Line spacing attribute
                          attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
                  
                  
                          // (Swift 4.1 and 4.0) Line spacing attribute
                          attributedString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
                  
                          self.attributedText = attributedString
                      }
                  }
                  

                  现在调用分机功能

                  let label = UILabel()
                  let stringValue = "Set\nUILabel\nline\nspacing"
                  
                  // Pass value for any one argument - lineSpacing or lineHeightMultiple
                  label.setLineSpacing(lineSpacing: 2.0) .  // try values 1.0 to 5.0
                  
                  // or try lineHeightMultiple
                  //label.setLineSpacing(lineHeightMultiple = 2.0) // try values 0.5 to 2.0
                  

                  或使用标签实例(只需复制并执行此代码即可查看结果)

                  let label = UILabel()
                  let stringValue = "Set\nUILabel\nline\nspacing"
                  let attrString = NSMutableAttributedString(string: stringValue)
                  var style = NSMutableParagraphStyle()
                  style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
                  style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40
                  
                  // Line spacing attribute
                  attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value: style, range: NSRange(location: 0, length: stringValue.characters.count))
                  
                  // Character spacing attribute
                  attrString.addAttribute(NSAttributedStringKey.kern, value: 2, range: NSMakeRange(0, attrString.length))
                  
                  label.attributedText = attrString
                  

                  斯威夫特 3

                  let label = UILabel()
                  let stringValue = "Set\nUILabel\nline\nspacing"
                  let attrString = NSMutableAttributedString(string: stringValue)
                  var style = NSMutableParagraphStyle()
                  style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
                  style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40
                  attrString.addAttribute(NSParagraphStyleAttributeName, value: style, range: NSRange(location: 0, length: stringValue.characters.count))
                  label.attributedText = attrString
                  

                  【讨论】:

                  • “NSAttributedStringKey.paragraphStyle”有错误,我改用“NSParagraphStyleAttributeName”。
                  • @Alfi - 这是 Swift 语言版本的区别。您的项目的快速语言。版本可能是 swift 3.x,这里是两个版本的答案。尝试使用 Swift 3 代码。
                  • 嗨@krunal,我已经在界面中设置了 Linespacing 和 LineHeight,并且我以编程方式在 UILabel 中设置了文本,但它不起作用。如果我在界面中添加文本,那么它就可以工作。你能帮我吗?谢谢,我还在 UILabel 中设置了属性文本和文本,但这种方法对我不起作用。
                  • 界面生成器解决方案仅适用于静态文本。当我们在代码中添加属性字符串时,不会应用从界面生成器添加的那些属性。
                  【解决方案11】:

                  Dipen 为 Swift 4 更新了答案

                  let attr = NSMutableAttributedString(string: today)
                  let paragraphStyle = NSMutableParagraphStyle()
                  paragraphStyle.lineSpacing = 2
                  attr.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, attr.length))
                  label.attributedText = attr;
                  

                  【讨论】:

                  • 这不是 Swift 4.
                  【解决方案12】:

                  您可以在storyboard中控制行距。

                  Same question.

                  【讨论】:

                  • 我真的试过这个。但它不起作用。这对自定义字体也没有用。
                  • 如果您在自定义字体中遇到对齐错误,请尝试将ascender 属性更新为mentioned here。
                  • 不是错位问题。我无法使用您说的解决方案选择我的自定义字体@pkc456
                  • 不是错位问题。我无法选择我的自定义字体。但现在我通过在属性中单独添加我的字体解决了这个问题。但间距仍然保持不变。@pkc456
                  • 这仅适用于静态文本。尝试以编程方式添加文本。这行不通。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-01-02
                  • 1970-01-01
                  • 2016-05-03
                  • 2021-08-16
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-02-01
                  相关资源
                  最近更新 更多