** sizeToFit**
func sizeToFit()
這是一個 UIView 的方法。意思是調(diào)整和移動 view 和 view 內(nèi)部子視圖的大小和位置。
當(dāng)你想要調(diào)整當(dāng)前視圖,以便它使用最合適的空間的時候調(diào)用這個方法時。特定的 UIKit View 視圖是根據(jù)內(nèi)部需要進(jìn)行尺寸調(diào)整。在特定條件下,如果 view 沒有父視圖,他會根據(jù) 屏幕的 bounds 來進(jìn)行調(diào)整。如果你需要 view 根據(jù)父視圖來調(diào)整大小,就需要將 view 添加到 父視圖中。
你不可以直接對這個方法進(jìn)行重寫,如果你需要改變視圖的默認(rèn)尺寸信息,你可以重載 sizeThatFits(_:) 方法。在這個方法里面可以進(jìn)行一些必要的計算并在這個方法中對計算的結(jié)果進(jìn)行返回。
** sizeThatFits**
func sizeThatFits(_ size: CGSize) -> CGSize
要求視圖去計算和返回一個最適合指定尺寸的尺寸。
傳入:是一個指定的最適合的尺寸。
返回:是 view 的 子 view 最適合的尺寸。
默認(rèn)實(shí)現(xiàn)是返回 view 自己的 size
子類可以重寫這個方法來返回 subview 布局要求的一些 size 值。
例如:
- UISwitch 返回一個固定尺寸的值去顯示一個標(biāo)準(zhǔn)的切換視圖。
- UIImageView 會返回當(dāng)前顯示 image 的尺寸。
這個方法不會去設(shè)置 調(diào)用者 view 的 size
注意點(diǎn):
- 調(diào)用 sizeToFit() 會去自動調(diào)用 sizeThatFits(_ size: CGSize) 方法。
- sizeToFit不應(yīng)該在子類中被重寫,應(yīng)該重寫sizeThatFits。
- sizeThatFits 傳入的參數(shù)是receiver當(dāng)前的size,返回一個適合子 view 的size。
- sizeToFit 可以被手動直接調(diào)用。
- sizeToFit 和 sizeThatFits方法都沒有遞歸,對subviews也不負(fù)責(zé),只負(fù)責(zé)自己。
- sizeThatFits 不會改變 receiver 的 size, 調(diào)用 sizeToFit() 會改變 receiver 的 size
所以我們一般在實(shí)際開發(fā)中并不怎么用 但是在一些系統(tǒng)自動布局的場合我們用sizeToFit就比較適合了
- 對navigationItem的設(shè)置,
- 對UIBarButtonItem的設(shè)置
- Label
- imageView
在XIB或者storyboard中,可以使用 “command” + “=” 鍵組合讓控件自適應(yīng)大小。
在代碼書寫中可以通過 sizeToFit 函數(shù),來讓控件自適應(yīng)。
測試
1. sizeToFit 在 lable 上的使用
固定文本
let label = UILabel()
// 寬和高度都設(shè)置為0
label.frame = CGRect(x: 7, y: 74, width: 0, height: 0)
label.text = "1234567890qwertyuiopasdfghjklzxcvbnm"
// 多行顯示
label.numberOfLines = 0
/* sizeToFit() 和 addSubview 的先后順序沒有關(guān)系 */
label.sizeToFit()
self.label = label
view.addSubview(label)

修改寬度
label.frame = CGRect(x: 7, y: 74, width: view.frame.size.width - 20, height: 0)
當(dāng)給定寬度后 調(diào)用 sizeToFit() 就可以正確的獲取 lable 的 size

動態(tài)的調(diào)整文本
var label: UILabel?
var label1: UILabel?
override func viewDidLoad() {
super.viewDidLoad()
// 動態(tài)調(diào)用 sizeToFit()
let label1 = UILabel()
self.label1 = label1
// 設(shè)置文本的 width 為 0
label1.frame = CGRect(x: 10, y: 74 + 100, width: 0, height: 0)
label1.numberOfLines = 0
view.addSubview(label1)
let textF = UITextField(frame: CGRect(x: 10, y: view.frame.size.height - 50 , width: view.frame.size.width - 20, height: 30))
textF.borderStyle = .roundedRect
textF.addTarget(self, action: #selector(textChange), for: .editingChanged)
view.addSubview(textF)
let btn = UIButton()
btn.setTitle("size to fit", for: UIControlState.normal)
btn.setTitleColor(UIColor.white(), for: .normal)
btn.frame = CGRect(x: 10, y: textF.frame.origin.y - 50, width: 100, height: 44)
btn.backgroundColor = UIColor.red()
btn.addTarget(self, action: #selector(lableSizeToFit), for: .touchUpInside)
view.addSubview(btn)
}
func textChange (sender: UITextField ){
label1?.text = sender.text
// label1?.sizeToFit()
}
func lableSizeToFit() {
label1?.sizeToFit()
print(view?.constraints)
print(label1)
}
Lable 的 width 為 0

當(dāng)輸入文本,第一次調(diào)用 sizeToFit() 后就確認(rèn)了 lable 的 width, 在后續(xù)的調(diào)用 sizeToFit() 只會修改 lable 的高度。
設(shè)置 Lable 的 width 為 view.frame.size.width - 20


當(dāng)輸入文本,第一次調(diào)用 sizeToFit()后, 如果 調(diào)用 sizeToFit()后得到 lable 的 width 小于 lalbe 的 bounds.width , 就會以 sizeToFit()后得到 lable 的 width為 lable 的 width。 在后續(xù)的調(diào)用 sizeToFit() 只會修改 lable 的高度。
- numberOfLines = 1 的時候調(diào)用 sizeToFit() 只會修改 label 的 width
- numberOfLines != 1 的時候調(diào)用 sizeToFit() 的時候會在第一調(diào)用的時候確認(rèn) label 的 width。
- 如果 調(diào)用 sizeToFit() 得到的寬度小于 label.bounds.width 就會以 調(diào)用 sizeToFit() 得到的寬度 作為 label 的 width 。
- 大于就會以 label.bounds.width 作為 label 的寬度。
2. sizeToFit 在 imageView 上的使用
let imageView = UIImageView()
imageView.sizeToFit()
view.addSubview(imageView)
是將ImageView的frame的size調(diào)整為與內(nèi)容image的size一致。。