核心文本 - NSAttributedString 行高做得对吗?

发布于 2024-12-15 09:14:14 字数 435 浏览 2 评论 0原文

我对 Core Text 的行距一无所知。我正在使用 NSAttributedString 并在其上指定以下属性: - kCTFont属性名称 - kCTParagraphStyleAttributeName

由此创建 CTFrameSetter 并将其绘制到上下文中。

在段落样式属性中,我想指定行的高度。

当我使用 kCTParagraphStyleSpecifierLineHeightMultiple 时,每行都会在文本顶部接收填充,而不是在该高度的中间显示文本。

当我使用 kCTParagraphStyleSpecifierLineSpacing 时,文本底部会添加填充。

请帮助我实现指定的行高,其中文本(字形)位于该高度的中间,而不是文本位于行的底部或顶部。

如果不显式创建 CTLine 等,这是否不可能?

I'm completely in the dark with Core Text's line spacing. I'm using NSAttributedString and I specify the following attributes on it:
- kCTFontAttributeName
- kCTParagraphStyleAttributeName

From this the CTFrameSetter gets created and drawn to context.

In the paragraph style attribute I'd like to specify the height of the lines.

When I use kCTParagraphStyleSpecifierLineHeightMultiple each line receives padding at the top of the text, instead of the text being displayed in the middle of this height.

When I use kCTParagraphStyleSpecifierLineSpacing a padding is added to the bottom of the text.

Please help me achieve a specified line height with the text(glyphs) in the middle of that height, instead of the text sitting either at the bottom or the top of the line.

Is this not possible without going down the route of explicitly creating CTLine 's and so forth?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

苦行僧 2024-12-22 09:14:15

您可以从故事板以及以编程方式设置/更新行距和行高倍数。

从 Interface Builder:

在此处输入图像描述

以编程方式:

SWift 4

extension UILabel {

    // Pass value for any one of both parameters and see result
    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)
        }

        // Line spacing attribute

// Swift 4.2++


attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))

// Swift 4.1--
attributedString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))

        self.attributedText = attributedString
    }
}

现在调用扩展函数

let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"

// 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 = "How to\ncontrol\nthe\nline spacing\nin UILabel"
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

// Swift 4.2++
// Line spacing attribute
attrString.addAttribute(NSAttributedString.Key.paragraphStyle, value: style, range: NSRange(location: 0, length: stringValue.characters.count))

// Character spacing attribute
attrString.addAttribute(NSAttributedString.Key.kern, value: 2, range: NSMakeRange(0, attrString.length))


// Swift 4.1--
// 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 = "How to\ncontrol\nthe\nline spacing\nin UILabel"
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

You can set/update line spacing and line height multiple from storyboard as well as programatically.

From Interface Builder:

enter image description here

Programmatically:

SWift 4

extension UILabel {

    // Pass value for any one of both parameters and see result
    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)
        }

        // Line spacing attribute

// Swift 4.2++


attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))

// Swift 4.1--
attributedString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))

        self.attributedText = attributedString
    }
}

Now call extension function

let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"

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

Or using label instance (Just copy & execute this code to see result)

let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"
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

// Swift 4.2++
// Line spacing attribute
attrString.addAttribute(NSAttributedString.Key.paragraphStyle, value: style, range: NSRange(location: 0, length: stringValue.characters.count))

// Character spacing attribute
attrString.addAttribute(NSAttributedString.Key.kern, value: 2, range: NSMakeRange(0, attrString.length))


// Swift 4.1--
// 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 = "How to\ncontrol\nthe\nline spacing\nin UILabel"
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
南…巷孤猫 2024-12-22 09:14:15

我尝试了所有这些答案,但要真正获得 Sketch 或 Zeplin 设计文件中通常出现的精确线高,那么您需要:

let ps = NSMutableParagraphStyle()
ps.minimumLineHeight = 34
ps.maximumLineHeight = 34
let attrText = NSAttributedString(
    string: "Your long multiline text that will have exact line height spacing",
    attributes: [
        .paragraphStyle: ps
    ]
)
someLabel.attributedText = attrText
someLabel.numberOfLines = 2
...

I tried all these answers, but to really get the EXACT line height that usually comes in design files from Sketch or Zeplin then you need to:

let ps = NSMutableParagraphStyle()
ps.minimumLineHeight = 34
ps.maximumLineHeight = 34
let attrText = NSAttributedString(
    string: "Your long multiline text that will have exact line height spacing",
    attributes: [
        .paragraphStyle: ps
    ]
)
someLabel.attributedText = attrText
someLabel.numberOfLines = 2
...
心作怪 2024-12-22 09:14:15

我为此做了一个扩展,见下文。使用扩展,您可以像这样设置行高:

let label = UILabel()
label.lineHeight = 19 

这是扩展:

// Put this in a file called UILabel+Lineheight.swift, or whatever else you want to call it

import UIKit

extension UILabel {

    var lineHeight: CGFloat {
        set {
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.minimumLineHeight = newValue
            paragraphStyle.maximumLineHeight = newValue
            _setAttribute(key: NSAttributedString.Key.paragraphStyle, value: paragraphStyle)
        }
        get {
            let paragraphStyle = _getAttribute(key: NSAttributedString.Key.paragraphStyle) as? NSParagraphStyle
            return paragraphStyle?.minimumLineHeight ?? 0
        }
    }

    func _getAttribute(key: NSAttributedString.Key) -> Any? {
        return attributedText?.attribute(key, at: 0, effectiveRange: .none)
    }

    func _setAttribute(key: NSAttributedString.Key, value: Any) {
        let attributedString: NSMutableAttributedString!
        if let currentAttrString = attributedText {
            attributedString = NSMutableAttributedString(attributedString: currentAttrString)
        } else {
            attributedString = NSMutableAttributedString(string: text ?? "")
            text = nil
        } 
        attributedString.addAttribute(key,
                                      value: value,
                                      range: NSRange(location: 0, length: attributedString.length))
        attributedText = attributedString
    }
}

注意:

  • 我不喜欢行高倍数。我的设计文档包含一个高度,例如 20,而不是倍数。
  • 与其他一些答案一样,lineSpacing 是完全不同的。不是你想要的。
  • 那里有一个额外的 _set/_getAttribute 方法的原因是我使用相同的方法来设置字母间距。也可以用于任何其他 NSAttributedString 值,但似乎我只擅长字母间距(Swift/UIKit 中的字距调整)和行高。

I made an extension for this, see below. With the extension you can just set the line height like so:

let label = UILabel()
label.lineHeight = 19 

This is the extension:

// Put this in a file called UILabel+Lineheight.swift, or whatever else you want to call it

import UIKit

extension UILabel {

    var lineHeight: CGFloat {
        set {
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.minimumLineHeight = newValue
            paragraphStyle.maximumLineHeight = newValue
            _setAttribute(key: NSAttributedString.Key.paragraphStyle, value: paragraphStyle)
        }
        get {
            let paragraphStyle = _getAttribute(key: NSAttributedString.Key.paragraphStyle) as? NSParagraphStyle
            return paragraphStyle?.minimumLineHeight ?? 0
        }
    }

    func _getAttribute(key: NSAttributedString.Key) -> Any? {
        return attributedText?.attribute(key, at: 0, effectiveRange: .none)
    }

    func _setAttribute(key: NSAttributedString.Key, value: Any) {
        let attributedString: NSMutableAttributedString!
        if let currentAttrString = attributedText {
            attributedString = NSMutableAttributedString(attributedString: currentAttrString)
        } else {
            attributedString = NSMutableAttributedString(string: text ?? "")
            text = nil
        } 
        attributedString.addAttribute(key,
                                      value: value,
                                      range: NSRange(location: 0, length: attributedString.length))
        attributedText = attributedString
    }
}

Notes:

  • I don't like line height multiples. My design document contains a height, like 20, not a multiple.
  • lineSpacing as in some other answers is something totally different. Not what you want.
  • The reason there's an extra _set/_getAttribute method in there is that I use the same method for setting letter spacing. Could also be used for any other NSAttributedString values but seems like I'm good with just letter spacing (kerning in Swift/UIKit) and line height.
享受孤独 2024-12-22 09:14:15

NSParagraphStyle 有两个属性可以修改同一段落中的连续文本基线之间的高度:lineSpacinglineHeightMultiple 。 @Schoob 是对的,1.0 以上的 lineHeightMultiple 在文本上方添加了额外的空间,而 0.0 以上的 lineSpacing 添加了文本下方的空间。 此图显示了各个维度之间的关系。

因此,为了使文本保持居中,目的是根据另一个属性来指定一个属性,这样我们通过一个属性(顶部/底部)添加的任何“填充”都可以通过确定另一个属性的填充(底部/底部)来平衡。顶部)来匹配。换句话说,添加的任何额外空间都会均匀分布,同时保留文本的现有位置。

好处是,通过这种方式,您可以选择要指定的属性,然后确定另一个:

extension UIFont
{
    func lineSpacingToMatch(lineHeightMultiple: CGFloat) -> CGFloat {
        return self.lineHeight * (lineHeightMultiple - 1)
    }

    func lineHeightMultipleToMatch(lineSpacing: CGFloat) -> CGFloat {
        return 1 + lineSpacing / self.lineHeight
    }
}

从这里开始,其他答案显示了如何在 NSAttributedString 中设置这两个属性,但这应该回答两者如何与“居中”文本相关。

There are two properties of NSParagraphStyle that modify the height between successive text baselines in the same paragraph: lineSpacing and lineHeightMultiple. @Schoob is right that a lineHeightMultiple above 1.0 adds additional space above the text, while a lineSpacing above 0.0 adds space below the text. This diagram shows how the various dimensions are related.

To get the text to stay centred the aim is therefore to specify one in terms of the other, in such a way that any 'padding' we add by one attribute (top/bottom) is balanced by determining the other attribute's padding (bottom/top) to match. In other words, any extra space added is distributed evenly while otherwise preserving the text's existing positioning.

The nice thing is that this way you can choose which attribute you want to specify and then just determine the other:

extension UIFont
{
    func lineSpacingToMatch(lineHeightMultiple: CGFloat) -> CGFloat {
        return self.lineHeight * (lineHeightMultiple - 1)
    }

    func lineHeightMultipleToMatch(lineSpacing: CGFloat) -> CGFloat {
        return 1 + lineSpacing / self.lineHeight
    }
}

From here, other answers show how these two attributes can be set in an NSAttributedString, but this should answer how the two can be related to 'centre' the text.

揽月 2024-12-22 09:14:15

Swift 4 和5

extension NSAttributedString {

    /// Returns a new instance of NSAttributedString with same contents and attributes with line spacing added.
     /// - Parameter spacing: value for spacing you want to assign to the text.
     /// - Returns: a new instance of NSAttributedString with given line spacing.
     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)
     }
}

Swift 4 & 5

extension NSAttributedString {

    /// Returns a new instance of NSAttributedString with same contents and attributes with line spacing added.
     /// - Parameter spacing: value for spacing you want to assign to the text.
     /// - Returns: a new instance of NSAttributedString with given line spacing.
     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)
     }
}
汐鸠 2024-12-22 09:14:15

这在 Xcode 7.2 中对我有用。 iOS 9.2.1。 (斯威夫特 2.1。):

  dispatch_async(dispatch_get_main_queue()) { () -> Void in
        let paragraphStyleWithSpacing           = NSMutableParagraphStyle()
        paragraphStyleWithSpacing.lineSpacing   = 2.0 //CGFloat
        let textWithLineSpacing                 = NSAttributedString(string: str, attributes: [NSParagraphStyleAttributeName : paragraphStyleWithSpacing])
        self.MY_TEXT_VIEW_NAME.attributedText   = textWithLineSpacing
    }

This worked for me in Xcode 7.2. iOS 9.2.1. (Swift 2.1.):

  dispatch_async(dispatch_get_main_queue()) { () -> Void in
        let paragraphStyleWithSpacing           = NSMutableParagraphStyle()
        paragraphStyleWithSpacing.lineSpacing   = 2.0 //CGFloat
        let textWithLineSpacing                 = NSAttributedString(string: str, attributes: [NSParagraphStyleAttributeName : paragraphStyleWithSpacing])
        self.MY_TEXT_VIEW_NAME.attributedText   = textWithLineSpacing
    }
极致的悲 2024-12-22 09:14:15

使用 NSAttributedString 线位置进行扭动的另一种方法是玩
baselineOffset 属性:

let contentText = NSMutableAttributedString(
string: "I see\nI'd think it`d be both a notification and a\nplace to see past announcements\nLike a one way chat.")

contentText.addAttribute(.baselineOffset, value: 10, range: NSRange(location: 0, length: 5))
contentText.addAttribute(.baselineOffset, value: -10, range: NSRange(location: 85, length: 20))

结果:

“我明白了

我认为这既是通知又是

查看过去公告的地方

就像单向聊天一样。”

https://stackoverflow.com/a/55876401/4683601

Another way of twerking with a NSAttributedString line position is playing with
baselineOffset attribute:

let contentText = NSMutableAttributedString(
string: "I see\nI'd think it`d be both a notification and a\nplace to see past announcements\nLike a one way chat.")

contentText.addAttribute(.baselineOffset, value: 10, range: NSRange(location: 0, length: 5))
contentText.addAttribute(.baselineOffset, value: -10, range: NSRange(location: 85, length: 20))

Result:

"I see

I'd think it`d be both a notification and a

place to see past announcements

Like a one way chat."

https://stackoverflow.com/a/55876401/4683601

妳是的陽光 2024-12-22 09:14:14

Objective-C

NSInteger strLength = [myString length];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:24];
[attString addAttribute:NSParagraphStyleAttributeName
                  value:style
                  range:NSMakeRange(0, strLength)];

Swift 5

let strLength = myString.length()
var style = NSMutableParagraphStyle()
style.lineSpacing = 24
attString.addAttribute(.paragraphStyle, value: style, range: NSRange(location: 0, length: strLength))

Objective-C

NSInteger strLength = [myString length];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:24];
[attString addAttribute:NSParagraphStyleAttributeName
                  value:style
                  range:NSMakeRange(0, strLength)];

Swift 5

let strLength = myString.length()
var style = NSMutableParagraphStyle()
style.lineSpacing = 24
attString.addAttribute(.paragraphStyle, value: style, range: NSRange(location: 0, length: strLength))
雨夜星沙 2024-12-22 09:14:14

我对下面的说法仍然不是100%有信心,但似乎有道理。有不对的地方请指正。

行高(行距)是指连续行的基线之间的距离。这里的基线可以解释为文本所在的假想线。

行距是行与行之间的间距。空格出现在文本行之后。

我最终使用以下解决方案来解决我的问题:

// NOT SURE WHAT THE THEORY BEHIND THIS FACTOR IS. WAS FOUND VIA TRIAL AND ERROR.
    CGFloat factor = 14.5/30.5;
    CGFloat floatValues[4];
    floatValues[0] = self.lineHeight * factor/(factor + 1);
    floatValues[1] = self.lineHeight/(factor + 1);
    floatValues[2] = self.lineHeight;

此矩阵与 NSAttributedString 的段落样式参数一起使用:

CTParagraphStyleSetting paragraphStyle[3];

paragraphStyle[0].spec = kCTParagraphStyleSpecifierLineSpacing;
paragraphStyle[0].valueSize = sizeof(CGFloat);
paragraphStyle[0].value = &floatValues[0];

paragraphStyle[1].spec = kCTParagraphStyleSpecifierMinimumLineHeight;
paragraphStyle[1].valueSize = sizeof(CGFloat);
paragraphStyle[1].value = &floatValues[1];

paragraphStyle[2].spec = kCTParagraphStyleSpecifierMaximumLineHeight;
paragraphStyle[2].valueSize = sizeof(CGFloat);
paragraphStyle[2].value = &floatValues[2];

CTParagraphStyleRef style = CTParagraphStyleCreate((const CTParagraphStyleSetting*) ¶graphStyle, 3);
[attributedString addAttribute:(NSString*)kCTParagraphStyleAttributeName value:(id)style range:NSMakeRange(0, [string length])];
CFRelease(style);

希望这对某人有帮助。当我发现更多相关信息时,我会更新这个答案。

I'm still not 100% confident in my following statements, but it seems to make sense. Please correct me where I am wrong.

The line height (leading) refers to the distance between the baselines of successive lines of type. The baseline here can be interpreted as the imaginary line which the text sits on.

Spacing is the space between lines. The space appears after the line of text.

I ended up using the following solution to my problem:

// NOT SURE WHAT THE THEORY BEHIND THIS FACTOR IS. WAS FOUND VIA TRIAL AND ERROR.
    CGFloat factor = 14.5/30.5;
    CGFloat floatValues[4];
    floatValues[0] = self.lineHeight * factor/(factor + 1);
    floatValues[1] = self.lineHeight/(factor + 1);
    floatValues[2] = self.lineHeight;

This matrix is used with the paragraph style parameter for NSAttributedString:

CTParagraphStyleSetting paragraphStyle[3];

paragraphStyle[0].spec = kCTParagraphStyleSpecifierLineSpacing;
paragraphStyle[0].valueSize = sizeof(CGFloat);
paragraphStyle[0].value = &floatValues[0];

paragraphStyle[1].spec = kCTParagraphStyleSpecifierMinimumLineHeight;
paragraphStyle[1].valueSize = sizeof(CGFloat);
paragraphStyle[1].value = &floatValues[1];

paragraphStyle[2].spec = kCTParagraphStyleSpecifierMaximumLineHeight;
paragraphStyle[2].valueSize = sizeof(CGFloat);
paragraphStyle[2].value = &floatValues[2];

CTParagraphStyleRef style = CTParagraphStyleCreate((const CTParagraphStyleSetting*) ¶graphStyle, 3);
[attributedString addAttribute:(NSString*)kCTParagraphStyleAttributeName value:(id)style range:NSMakeRange(0, [string length])];
CFRelease(style);

Hope this helps someone. I'll update this answer as I discover more relevant information.

苦行僧 2024-12-22 09:14:14

在 Swift 3 中:

    let textFont = UIFont(name: "Helvetica Bold", size: 20)!
    let textColor = UIColor(white: 1, alpha: 1)      // White
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.paragraphSpacing = 20             // Paragraph Spacing
    paragraphStyle.lineSpacing = 40                  // Line Spacing

    let textFontAttributes = [
        NSFontAttributeName: textFont,
        NSForegroundColorAttributeName: textColor,
        NSParagraphStyleAttributeName: paragraphStyle
        ] as [String : Any]

In Swift 3:

    let textFont = UIFont(name: "Helvetica Bold", size: 20)!
    let textColor = UIColor(white: 1, alpha: 1)      // White
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.paragraphSpacing = 20             // Paragraph Spacing
    paragraphStyle.lineSpacing = 40                  // Line Spacing

    let textFontAttributes = [
        NSFontAttributeName: textFont,
        NSForegroundColorAttributeName: textColor,
        NSParagraphStyleAttributeName: paragraphStyle
        ] as [String : Any]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文