** sizeToFit**
func sizeToFit()
这是一个 UIView 的方法。意思是调整和移动 view 和 view 内部子视图的大小和位置。
当你想要调整当前视图,以便它使用最合适的空间的时候调用这个方法时。特定的 UIKit View 视图是根据内部需要进行尺寸调整。在特定条件下,如果 view 没有父视图,他会根据 屏幕的 bounds 来进行调整。如果你需要 view 根据父视图来调整大小,就需要将 view 添加到 父视图中。
你不可以直接对这个方法进行重写,如果你需要改变视图的默认尺寸信息,你可以重载 sizeThatFits(_:) 方法。在这个方法里面可以进行一些必要的计算并在这个方法中对计算的结果进行返回。
** sizeThatFits**
func sizeThatFits(_ size: CGSize) -> CGSize
要求视图去计算和返回一个最适合指定尺寸的尺寸。
传入:是一个指定的最适合的尺寸。
返回:是 view 的 子 view 最适合的尺寸。
默认实现是返回 view 自己的 size
子类可以重写这个方法来返回 subview 布局要求的一些 size 值。
例如:
- UISwitch 返回一个固定尺寸的值去显示一个标准的切换视图。
- UIImageView 会返回当前显示 image 的尺寸。
这个方法不会去设置 调用者 view 的 size
注意点:
- 调用 sizeToFit() 会去自动调用 sizeThatFits(_ size: CGSize) 方法。
- sizeToFit不应该在子类中被重写,应该重写sizeThatFits。
- sizeThatFits 传入的参数是receiver当前的size,返回一个适合子 view 的size。
- sizeToFit 可以被手动直接调用。
- sizeToFit 和 sizeThatFits方法都没有递归,对subviews也不负责,只负责自己。
- sizeThatFits 不会改变 receiver 的 size, 调用 sizeToFit() 会改变 receiver 的 size
所以我们一般在实际开发中并不怎么用 但是在一些系统自动布局的场合我们用sizeToFit就比较适合了
- 对navigationItem的设置,
- 对UIBarButtonItem的设置
- Label
- imageView
在XIB或者storyboard中,可以使用 “command” + “=” 键组合让控件自适应大小。
在代码书写中可以通过 sizeToFit 函数,来让控件自适应。
测试
1. sizeToFit 在 lable 上的使用
固定文本
let label = UILabel()
// 宽和高度都设置为0
label.frame = CGRect(x: 7, y: 74, width: 0, height: 0)
label.text = "1234567890qwertyuiopasdfghjklzxcvbnm"
// 多行显示
label.numberOfLines = 0
/* sizeToFit() 和 addSubview 的先后顺序没有关系 */
label.sizeToFit()
self.label = label
view.addSubview(label)
修改宽度
label.frame = CGRect(x: 7, y: 74, width: view.frame.size.width - 20, height: 0)
当给定宽度后 调用 sizeToFit() 就可以正确的获取 lable 的 size
动态的调整文本
var label: UILabel?
var label1: UILabel?
override func viewDidLoad() {
super.viewDidLoad()
// 动态调用 sizeToFit()
let label1 = UILabel()
self.label1 = label1
// 设置文本的 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
当输入文本,第一次调用 sizeToFit() 后就确认了 lable 的 width, 在后续的调用 sizeToFit() 只会修改 lable 的高度。
设置 Lable 的 width 为 view.frame.size.width - 20
当输入文本,第一次调用 sizeToFit()后, 如果 调用 sizeToFit()后得到 lable 的 width 小于 lalbe 的 bounds.width , 就会以 sizeToFit()后得到 lable 的 width为 lable 的 width。 在后续的调用 sizeToFit() 只会修改 lable 的高度。
- numberOfLines = 1 的时候调用 sizeToFit() 只会修改 label 的 width
- numberOfLines != 1 的时候调用 sizeToFit() 的时候会在第一调用的时候确认 label 的 width。
- 如果 调用 sizeToFit() 得到的宽度小于 label.bounds.width 就会以 调用 sizeToFit() 得到的宽度 作为 label 的 width 。
- 大于就会以 label.bounds.width 作为 label 的宽度。
2. sizeToFit 在 imageView 上的使用
let imageView = UIImageView()
imageView.sizeToFit()
view.addSubview(imageView)
是将ImageView的frame的size调整为与内容image的size一致。。