在我的应用程序中,我有一个预设有两行的 UILabel
。我可以将文本对齐方式设置为 .left
或 .justified
。
如果我将其设置为 .left
,如果一行中的最后一个单词与标签的最大 x 位置之间有足够的空间,则不会出现布局问题。然而,当没有那么多空间时,最后一个单词非常接近最大 x 位置,它看起来有点奇怪,因为它并不完全右对齐(就像 .justified
.
如果我将其设置为.justified
,它总是对齐得很好,但有时各个字符之间的距离看起来很奇怪。
我正在寻找一种根据第一行最后一个单词到标签最大 x 位置之间的距离动态调整文本对齐方式的方法。比如说,如果最后一个单词的最后一个字符的位置小于 50,我想要文本对齐 .left
,否则我想要 .justified
。有什么办法可以实现这一点吗?
最佳答案
我采取了一种相当老套的方法,需要一些处理能力,但它似乎有效。
<小时/>首先,我使用此扩展获取标签第一行中的字符串:
import CoreText
extension UILabel {
/// Returns the String displayed in the first line of the UILabel or "" if text or font is missing
var firstLineString: String {
guard let text = self.text else { return "" }
guard let font = self.font else { return "" }
let rect = self.frame
let attStr = NSMutableAttributedString(string: text)
attStr.addAttribute(String(kCTFontAttributeName), value: CTFontCreateWithName(font.fontName as CFString, font.pointSize, nil), range: NSMakeRange(0, attStr.length))
let frameSetter = CTFramesetterCreateWithAttributedString(attStr as CFAttributedString)
let path = CGMutablePath()
path.addRect(CGRect(x: 0, y: 0, width: rect.size.width + 7, height: 100))
let frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, nil)
guard let line = (CTFrameGetLines(frame) as! [CTLine]).first else { return "" }
let lineString = text[text.startIndex...text.index(text.startIndex, offsetBy: CTLineGetStringRange(line).length-2)]
return lineString
}
}
之后,我计算宽度,使用此扩展的该字符串需要一个行号为 1 且固定高度的标签:
extension UILabel {
/// Get required width for a UILabel depending on its text content and font configuration
class func calculateWidth(text: String, height: CGFloat, font: UIFont) -> CGFloat {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: CGFloat.greatestFiniteMagnitude, height: height))
label.numberOfLines = 1
label.font = font
label.text = text
label.sizeToFit()
return label.frame.size.width
}
}
据此,我可以计算到右侧的距离,并决定是否选择文本对齐.left
或.justified
,所以主要代码如下所示:
// Set text
myLabel.text = someString
// Change text alignment depending on distance to right
let firstLineString = myLabel.firstLineString
let distanceToRight = myLabel.frame.size.width - UILabel.calculateWidth(text: firstLineString, height: myLabel.frame.size.height, font: myLabel.font)
myLabel.textAlignment = distanceToRight < 20 ? .justified : .left
关于ios - 动态设置 .left 和 .justified 之间的 UILabel 文本对齐方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40428504/