2016-11-04 10 views
0

私のアプリでは、UILabelの2行がプリセットされています。テキストの配置を.leftまたは.justifiedに設定できます。動的にUILabelのテキストアラインメントを.leftと.justedの間で設定します。

.leftに設定すると、行の最後の単語とラベルの最大x位置の間に十分なスペースがあれば、レイアウトに問題はありません。しかし、スペースがあまりないので、最後の単語が最大x位置に非常に近くなるので、ちょっと変わって見えます(.justifiedのように)

もし私が

私が探しているのは、最後の単語との間の距離に応じて動的にテキストの配置を調整する方法です最後の単語の最後の文字の位置が50より小さい場合、テキストの整列を.leftにしたい場合は、.justifiedを追加したいと思います。 wこれを達成する方法は?

+1

テキスト幅を測定するNSAttributedStringを使用してだけの問題:、その主なコードは次のようになりますか? –

答えて

0

私はかなりのハッキーなアプローチを取っていましたが、処理能力はいくらかかかりましたが、うまくいくようです。


まず、私はこの拡張機能を使用して、ラベルの最初の行の文字列をフェッチ:

その後
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 
関連する問題