最近項目中想要設置UILabel
中文字的內邊距也就是所謂的Inset
,在UILable
中沒有發現類似的屬性,一頓Google自己寫了一個UILabel
的子類來實現這個屬性,當然也可以通過給UILabel
套一個View的方式來實現,不過這個需求是在寫完之後發現的,所以通過子類的方式改起來更好一些。
首先找到了一部分說明需要重寫drawText(in rect: CGRect)
這個方法,代碼大概就是這個樣子,這個方法就是告訴UILabel要將文字顯示在什麼位置上,距邊框的距離是多少:
override func drawText(in rect: CGRect) {
//其中用到的self.edgeInsets是我們自己定義的一個屬性,在初始化UILabel實例的時候對其賦值
super.drawText(in: UIEdgeInsetsInsetRect(rect, self.edgeInsets))
}
重寫了這個方法之後發現在自動佈局中並沒有什麼太大的作用,然後我又發現了下面兩個東西,
var intrinsicContentSize: CGSize
這個是用來得到自動佈局中size
的屬性
sizeThatFits(_ size: CGSize) -> CGSize
這個猜測是sizeToFit
返回的size
大小
override var intrinsicContentSize: CGSize{
get{
var size = super.intrinsicContentSize;
size.width += (self.edgeInsets.left + self.edgeInsets.right);
size.height += (self.edgeInsets.top + self.edgeInsets.bottom);
return size;
}
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
let superSizeThatFits = super.sizeThatFits(size)
let width = superSizeThatFits.width + edgeInsets.left + edgeInsets.right
let height = superSizeThatFits.height + edgeInsets.top + edgeInsets.bottom
return CGSize(width: width, height: height)
}
在實現了這個方法之後發現在文字所佔的款度恰好等於UILabel
的寬度時(設置了edgeInset
的left
和right
且不爲0)是不會自動換行的,也就是我們的代碼寫的還是有問題的,雖然重寫了上面兩個方法,告訴了UILabel
要將文字畫在哪,最終的大小是多少但是UILabel
在填充的時候仍然是按照文字的寬度與最終UILabel
的寬度的比較來判斷是不是需要換行的,所以恰好這個臨界值是不會換行的,所以就會出現上面的情況,其實我們上面做的工作無非就是在UILabel
設置完內容之後告訴他你要在哪顯示內容,你最終的大小是啥,但是最後得到的大小還是UILabel
用自己的默認方式計算出來的。我們只是在其計算結果上設置了內邊距並體現在了最終顯示的結果上。
然後又是一頓Google,最後被我發現了preferredMaxLayoutWidth
這個屬性,這個屬性就是來指定UILabel
計算文字size
的時候的最大寬度時多少,默認情況下是以UILabel
的寬度來計算的然後我們在UILabel
的初始化方法中設置一下它的值,最後計算以及顯示就會是正常的了,最起碼在我的例子中是正常的。
由於我是通過StoryBoard做的所以之在下面的方法中修改了該值,理論上所有的init方法中都應該設置,當然是要在知道UILabel
的frame
之後才能計算
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.edgeInsets = UIEdgeInsetsMake(10, 5, 10, 5)
preferredMaxLayoutWidth = self.frame.width - (self.edgeInsets.left + self.edgeInsets.right)
}