如何在Swift中增加UILabel的行间距

时间:2016-08-26 05:04:29

标签: ios swift uilabel line-spacing

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

11 个答案:

答案 0 :(得分:105)

使用以下代码段以编程方式将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

Swift 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

答案 1 :(得分:62)

您可以在storyboard

中控制行间距

enter image description here

Same question.

答案 2 :(得分:62)

来自Interface Builder:

enter image description here

<强>编程:

SWift 4&amp; 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

Swift 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

答案 3 :(得分:5)

您可以使用此可重用的扩展名:

gaussian_filter

答案 4 :(得分:5)

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

Example

答案 5 :(得分:4)

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)

答案 6 :(得分:2)

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;

答案 7 :(得分:1)

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

答案 8 :(得分:0)

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

答案 9 :(得分:0)

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

例如:

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

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

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

答案 10 :(得分:0)

创建标签样式

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!