簡體   English   中英

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

[英]How to Increase Line spacing in UILabel in Swift

我有一個包含幾行文本的標簽,我想增加行之間的間距。 其他人也提出了類似的問題,但解決方案並不能解決我的問題。 此外,我的標簽可能包含也可能不包含段落。 我是Swift新手。 有沒有使用故事板的解決方案? 還是只有通過NSAttributedString可能?

使用以下代碼段以編程方式將 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

斯威夫特 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

從接口生成器:

在此處輸入圖片說明

以編程方式:

斯威夫特 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

您可以控制storyboard的行間距。

在此處輸入圖片說明

同樣的問題。

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)

您可以使用這個可重用的擴展:

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

斯威夫特 4 和斯威夫特 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

示例

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

除了使用屬性字符串和段落樣式,對於小的調整,字體描述符也可以派上用場。

例如:

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

這將創建一個前導較松散的字體,導致文本的行高比默認系統字體稍大(增加 2 磅)。 traitTightLeading也可以用於相反的效果(它將字體的前導減少 2 點)。

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

創建標簽樣式

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!

此解決方案適用於 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))

可用的

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM