内容に応じてサイズ変更するカスタムラベル
私は最初からラベルを作成しています。 (私の最終目的は、モンゴル語のスクリプトの縦書きのラベルを作ることですが、今のところ、通常の横書きのラベルを練習として作成しています)。カスタムビューのフレームをその本質的なコンテンツサイズに一致させる方法
長さと幅の制約がない限り、ラベルのフレームは、その固有のコンテンツサイズに従ってサイズ変更されます。
それは、IBのすべてではIB
に作品は、私はUILabel
、私のカスタムラベル(UIView
サブクラス)、およびボタンをテストする際に正常に動作しているようです。
これらのビューのそれぞれに上部および上部の制約を追加しますが、高さまたは幅の制約は設定しません。
私は(まだ任意の複数の制約を加えることなく)ストーリーボードにそれらのサイズを変更する場合は...
そして用ビュー内のすべてのビューをアップデートフレームを選択コントローラーでは、標準ラベルと私のカスタムラベルの両方が、固有のコンテンツサイズに合わせて適切にサイズ変更されます。私は、実行時にラベルのテキストを変更すると
これは、しかし、私のカスタムラベルの枠がリサイズされていない、実行中のアプリケーション
上では動作しません。 (私は一時的にライトブルーの背景色でカスタムラベルのフレームから、ここでそれを区別支援するために、テキストレイヤーにダークブルーのボーダーを追加しました。)
クリックすると、「変更のテキストは」
いますご覧のとおり、テキストレイヤフレームは変更されましたが、カスタムビューのフレームは変更されませんでした。
コード
これは私のカスタムラベルクラスです:
import UIKit
@IBDesignable
class UILabelFromScratch: UIView {
private let textLayer = CATextLayer()
@IBInspectable var text: String = "" {
didSet {
updateTextLayerFrame()
}
}
@IBInspectable var fontSize: CGFloat = 17 {
didSet {
updateTextLayerFrame()
}
}
// MARK: - Initialization
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
func setup() {
// Text layer
textLayer.borderColor = UIColor.blueColor().CGColor
textLayer.borderWidth = 1
textLayer.contentsScale = UIScreen.mainScreen().scale
layer.addSublayer(textLayer)
}
// MARK: Other methods
override func intrinsicContentSize() -> CGSize {
return textLayer.frame.size
}
func updateTextLayerFrame() {
let myAttribute = [ NSFontAttributeName: UIFont.systemFontOfSize(fontSize) ]
let attrString = NSMutableAttributedString(string: self.text, attributes: myAttribute)
let size = dimensionsForAttributedString(attrString)
textLayer.frame = CGRect(x: self.layer.bounds.origin.x, y: self.layer.bounds.origin.y, width: size.width, height: size.height)
textLayer.string = attrString
}
func dimensionsForAttributedString(attrString: NSAttributedString) -> CGSize {
var ascent: CGFloat = 0
var descent: CGFloat = 0
var width: CGFloat = 0
let line: CTLineRef = CTLineCreateWithAttributedString(attrString)
width = CGFloat(CTLineGetTypographicBounds(line, &ascent, &descent, nil))
// make width an even integer for better graphics rendering
width = ceil(width)
if Int(width)%2 == 1 {
width += 1.0
}
return CGSize(width: width, height: ceil(ascent+descent))
}
}
そしてここView Controllerクラスです:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var normalLabel: UILabel!
@IBOutlet weak var labelFromScratch: UILabelFromScratch!
@IBAction func changeTextButtonTapped(sender: UIButton) {
normalLabel.text = "Hello"
labelFromScratch.text = "Hello"
}
}
質問
UILabel
があることないこと、それを何ですか私はカスタムラベルに紛失していますか?
override func intrinsicContentSize() -> CGSize {
return textLayer.frame.size
}
は他に何私は何をする必要があります:私はintrinsicContentSize
をオーバーライド?