ChatGPT解决这个技术问题 Extra ChatGPT

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

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


D
Dipen Panchasara

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

这显示错误“'NSAttributedString' 类型的值没有成员 'addAttribute'”。
我们需要使用 NSMutableAttributedString 而不是 NSAttributedString。我已经更新了答案。
使用自定义字体也很棒@Dipen Panchasara
我不知道为什么,但对我来说,这只有在你设置行间距> = 1时才有效,我试图设置 0.5 / 0.75,它没有效果
不需要 NSMutableAttributedString。可以使用NSAttributedString(string: "Your text", attributes: [NSAttributedString.Key.paragraphStyle : paragraphStyle])
K
Krunal

从界面生成器:

https://i.stack.imgur.com/UmKYm.gif

以编程方式:

斯威夫特 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 代码。
Hii @krunal,我已经在界面中设置了 Linespacing 和 LineHeight 并且我以编程方式在 UILabel 中设置了文本,但它不起作用。如果我在界面中添加文本,那么它就可以工作。你能帮帮我吗谢谢,我还在 UILabel 中设置了属性文本和文本,但这种方法对我不起作用。
界面生成器解决方案仅适用于静态文本。当我们在代码中添加属性字符串时,不会应用从界面构建器添加的那些属性。
C
Community

您可以在 storyboard 中控制行距。

https://i.stack.imgur.com/w6TJN.gif

Same question.


我真的试过这个。但它不起作用。这对于自定义字体也没有用。
如果您在自定义字体中遇到对齐错误,请尝试将 ascender 属性更新为 mentioned here
它不是错位问题。我无法使用您所说的解决方案选择我的自定义字体@pkc456
它不是错位问题。我无法选择我的自定义字体。但现在我通过在属性中单独添加我的字体解决了这个问题。但间距仍然保持不变。@pkc456
这仅适用于静态文本。尝试以编程方式添加文本。这行不通。
A
Alexander Nikolenko

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 时才有效
为我工作。
A
Ahmadreza

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

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

p
pableiros

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

https://i.stack.imgur.com/pe4o7.png


M
Mike Carpenter

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。
А
Алмаз Рахматуллин
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

V
Venu Gopal Tewari
//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
          }

B
Beslan Tularov

创建标签样式

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!

D
Dirty Henry

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

例如:

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

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

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


g
gsk_fs

此解决方案适用于 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
}()