Я принял довольно хакерский подход, который требует некоторой вычислительной мощности, но, похоже, он работает.
Прежде всего, я извлечь строку в первой строке этикетки с помощью этого расширения:
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
Isnt это просто вопрос использования NSAttributedString для измерения ширины текста? –