私はかなりのハッキーなアプローチを取っていましたが、処理能力はいくらかかかりましたが、うまくいくようです。
まず、私はこの拡張機能を使用して、ラベルの最初の行の文字列をフェッチ:
その後
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
}
}
I幅を計算し、ラベル行番号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
またはを選択するかどうかを決定することができますそれイマイチ
// 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
テキスト幅を測定するNSAttributedStringを使用してだけの問題:、その主なコードは次のようになりますか? –