sizeToFit 的简单实用

** 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 值。

例如:

  1. UISwitch 返回一个固定尺寸的值去显示一个标准的切换视图。
  2. UIImageView 会返回当前显示 image 的尺寸。

这个方法不会去设置 调用者 view 的 size

注意点:

  1. 调用 sizeToFit() 会去自动调用 sizeThatFits(_ size: CGSize) 方法。
  2. sizeToFit不应该在子类中被重写,应该重写sizeThatFits。
  3. sizeThatFits 传入的参数是receiver当前的size,返回一个适合子 view 的size。
  4. sizeToFit 可以被手动直接调用。
  5. sizeToFit 和 sizeThatFits方法都没有递归,对subviews也不负责,只负责自己。
  6. sizeThatFits 不会改变 receiver 的 size, 调用 sizeToFit() 会改变 receiver 的 size

所以我们一般在实际开发中并不怎么用 但是在一些系统自动布局的场合我们用sizeToFit就比较适合了

  1. 对navigationItem的设置,
  2. 对UIBarButtonItem的设置
  3. Label
  4. 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)
Snip20160727_6.png

修改宽度

label.frame = CGRect(x: 7, y: 74, width: view.frame.size.width - 20, height: 0)

当给定宽度后 调用 sizeToFit() 就可以正确的获取 lable 的 size

Snip20160727_7.png

动态的调整文本

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


1.gif

当输入文本,第一次调用 sizeToFit() 后就确认了 lable 的 width, 在后续的调用 sizeToFit() 只会修改 lable 的高度。


设置 Lable 的 width 为 view.frame.size.width - 20

第一次调用 sizeToFit() 时,label text 的 width < view.frame.size.width - 20
第一次调用 sizeToFit() 时,label text 的 width > view.frame.size.width - 20

当输入文本,第一次调用 sizeToFit()后, 如果 调用 sizeToFit()后得到 lable 的 width 小于 lalbe 的 bounds.width , 就会以 sizeToFit()后得到 lable 的 width为 lable 的 width。 在后续的调用 sizeToFit() 只会修改 lable 的高度。


  1. numberOfLines = 1 的时候调用 sizeToFit() 只会修改 label 的 width
  2. 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一致。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容