最大行高截断文本
Maximum lineheight cutting off text
[
我想制作一个 pixelPerfect UI。我的设计师给了我一些特定字体的要求。我正在尝试实现它们,但我 运行 遇到了 paragraphStyle 的一些问题。所有文本优先基线必须位于网格上。将我的标题的 maximumLineHeight 设置为 24(2x 网格)时一切正常。但是,我的 bodyText 需要 lineHeight 为 16。这会切断第一行的顶部。
我试过设置标签高度,这只会增加布局冲突。我已经尝试将 firstBaseline 约束设置为远离其自身顶部的网格度量。无济于事。
我还覆盖了 UILabel 的绘制方法以添加一些额外的顶部填充。但是,无论我添加什么填充,这都会在我的代码中使用 fristBaseline 约束。很脏,只有最后的最后手段。
import Foundation
public class UILabelBody: UILabel {
override public var text: String? {
didSet {
let attributedString = NSMutableAttributedString(string: self.text!)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.maximumLineHeight = 16
attributedString.addAttributes([
NSAttributedString.Key.kern: 0.4,
NSAttributedString.Key.paragraphStyle : paragraphStyle],
range: NSMakeRange(0, attributedString.length))
self.attributedText = attributedString
}
}
public init() {
super.init(frame: CGRect.zero)
self.translatesAutoresizingMaskIntoConstraints = false
setup()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setup() {
self.font = UIFont(name: "Oxygen", size: 16)
self.textColor = UIColor(hexString: "1F1F1F")
}
}
这是我设置约束的class:
私有函数设置(){
self.addSubview(contentBox)
self.addSubview(imageView)
self.addSubview(title)
self.addSubview(body)
imageView.backgroundColor = UIColor.yellow.withAlphaComponent(0.8)
contentBox.backgroundColor = UIColor.red.withAlphaComponent(0.1)
title.backgroundColor = UIColor.orange.withAlphaComponent(0.2)
let padding = Layout.grid(1.5)
let highPriority = UILayoutPriority(1000)
let lowPrioririty = UILayoutPriority(100)
let titleFirstBaseline = title.firstBaselineAnchor.constraint(equalTo: contentBox.topAnchor, constant: Layout.grid(2.5))
let bodyFirstBaseLine = body.firstBaselineAnchor.constraint(equalTo: title.lastBaselineAnchor, constant: Layout.grid(2))
let selfHeight = self.heightAnchor.constraint(equalToConstant: Layout.grid(28))
let selfWidth = self.widthAnchor.constraint(equalToConstant: Layout.grid(30))
selfWidth.priority = highPriority
selfHeight.priority = lowPrioririty
titleFirstBaseline.priority = highPriority
bodyFirstBaseLine.priority = highPriority
NSLayoutConstraint.activate([
selfWidth,
selfHeight,
contentBox.topAnchor.constraint(equalTo: self.topAnchor, constant: padding),
contentBox.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: padding),
contentBox.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -padding),
contentBox.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -padding),
imageView.leadingAnchor.constraint(equalTo: contentBox.leadingAnchor),
imageView.topAnchor.constraint(equalTo: contentBox.topAnchor),
imageView.widthAnchor.constraint(equalToConstant: Layout.grid(4)),
imageView.heightAnchor.constraint(equalToConstant: Layout.grid(4)),
title.leadingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: padding),
titleFirstBaseline,
title.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -padding),
bodyFirstBaseLine,
body.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: padding),
body.bottomAnchor.constraint(equalTo: self.contentBox.bottomAnchor),
body.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -padding),
])
}
在刑讯室里待了几个小时后,我终于明白了!问题是字体本身。它是 .otf 而不是 .ttf。因为这个 swift 不理解字体的内部行高,就把它剪掉了。切换到 .ttf 后问题得到解决
[
我想制作一个 pixelPerfect UI。我的设计师给了我一些特定字体的要求。我正在尝试实现它们,但我 运行 遇到了 paragraphStyle 的一些问题。所有文本优先基线必须位于网格上。将我的标题的 maximumLineHeight 设置为 24(2x 网格)时一切正常。但是,我的 bodyText 需要 lineHeight 为 16。这会切断第一行的顶部。
我试过设置标签高度,这只会增加布局冲突。我已经尝试将 firstBaseline 约束设置为远离其自身顶部的网格度量。无济于事。 我还覆盖了 UILabel 的绘制方法以添加一些额外的顶部填充。但是,无论我添加什么填充,这都会在我的代码中使用 fristBaseline 约束。很脏,只有最后的最后手段。
import Foundation
public class UILabelBody: UILabel {
override public var text: String? {
didSet {
let attributedString = NSMutableAttributedString(string: self.text!)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.maximumLineHeight = 16
attributedString.addAttributes([
NSAttributedString.Key.kern: 0.4,
NSAttributedString.Key.paragraphStyle : paragraphStyle],
range: NSMakeRange(0, attributedString.length))
self.attributedText = attributedString
}
}
public init() {
super.init(frame: CGRect.zero)
self.translatesAutoresizingMaskIntoConstraints = false
setup()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setup() {
self.font = UIFont(name: "Oxygen", size: 16)
self.textColor = UIColor(hexString: "1F1F1F")
}
}
这是我设置约束的class: 私有函数设置(){
self.addSubview(contentBox)
self.addSubview(imageView)
self.addSubview(title)
self.addSubview(body)
imageView.backgroundColor = UIColor.yellow.withAlphaComponent(0.8)
contentBox.backgroundColor = UIColor.red.withAlphaComponent(0.1)
title.backgroundColor = UIColor.orange.withAlphaComponent(0.2)
let padding = Layout.grid(1.5)
let highPriority = UILayoutPriority(1000)
let lowPrioririty = UILayoutPriority(100)
let titleFirstBaseline = title.firstBaselineAnchor.constraint(equalTo: contentBox.topAnchor, constant: Layout.grid(2.5))
let bodyFirstBaseLine = body.firstBaselineAnchor.constraint(equalTo: title.lastBaselineAnchor, constant: Layout.grid(2))
let selfHeight = self.heightAnchor.constraint(equalToConstant: Layout.grid(28))
let selfWidth = self.widthAnchor.constraint(equalToConstant: Layout.grid(30))
selfWidth.priority = highPriority
selfHeight.priority = lowPrioririty
titleFirstBaseline.priority = highPriority
bodyFirstBaseLine.priority = highPriority
NSLayoutConstraint.activate([
selfWidth,
selfHeight,
contentBox.topAnchor.constraint(equalTo: self.topAnchor, constant: padding),
contentBox.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: padding),
contentBox.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -padding),
contentBox.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -padding),
imageView.leadingAnchor.constraint(equalTo: contentBox.leadingAnchor),
imageView.topAnchor.constraint(equalTo: contentBox.topAnchor),
imageView.widthAnchor.constraint(equalToConstant: Layout.grid(4)),
imageView.heightAnchor.constraint(equalToConstant: Layout.grid(4)),
title.leadingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: padding),
titleFirstBaseline,
title.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -padding),
bodyFirstBaseLine,
body.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: padding),
body.bottomAnchor.constraint(equalTo: self.contentBox.bottomAnchor),
body.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -padding),
])
}
在刑讯室里待了几个小时后,我终于明白了!问题是字体本身。它是 .otf 而不是 .ttf。因为这个 swift 不理解字体的内部行高,就把它剪掉了。切换到 .ttf 后问题得到解决