常见 UI 的 Intrinsic Content Size
View | Intrinsic ContentSize |
---|---|
UIView and NSView | 没有固有尺寸 |
Sliders | 仅确定宽度 |
Labels, buttons, switches, and text fields | 宽高都确定 |
Text views and image views | Intrinsic content 是变化的 |
Intrinsic ContentSize 是基于当前 view 的内容,label 和 button 的 Intrinsic ContentSize 是基于显示的内容和使用的字体。image 在没有图片的时候是没有 Intrinsic ContentSize 的,添加了图片后就是图片的尺寸。
Text views 的 Intrinsic ContentSize
- 可以滑动时是没有 Intrinsic ContentSize
- 不能滑动且没有指定 width 约束,Intrinsic ContentSize 是的单行文字的宽高
- 不能滑动且指定 width 约束,Intrinsic ContentSize 的高是内容展示的高度,宽度就是约束的宽度
对比 Intrinsic Content Size 与 Fitting Size
Intrinsic Content Size :固有尺寸(intrinsicSize) → 约束 (constraints)→ 布局(Layout),是 intrinsicSize 影响了布局,所以说它是 Auto Layout 的输入
- UILabel 等有 Intrinsic Content Size 的 UI ,我们只需要固定位置而不用指定大小,就是因为 ICS 影响了布局
Fitting Size:(布局)Layout → 合适尺寸(Fitting Size),是 Layout 得出了 fitting size ,所以说它是 Auto Layout 的输出
- 自适应 Cell、View 通过 Subviews 的 Content 来计算出 parent view 的 fitting size 的大小
如何给定义的 View 指定 Intrinsic Content Size
很简单我们需要重写 intrinsicContentSize 属性,如下
override var intrinsicContentSize: CGSize{
// 所有子类的 size 相加
// 如果子类是 label 等有 intrinsicContentSize属性的只需相加,没有的给指定一个。
return CGSize (width: 100, height: 200)
}
在 contentSize 变化时我们需要调用 invalidateIntrinsicContentSize 通知系统, 如下
override func layoutSubviews() {
super.layoutSubviews()
//此处加判断如果相等就不更新size
if self.bounds.size != intrinsicContentSize{
invalidateIntrinsicContentSize()
}
}
写布局的时,固定位置即可
NSLayoutConstraint.activate([
customerIntrinsicView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
customerIntrinsicView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
])
View 自适应 Auto Layout
IntrinsicContentSize:通过计算 subviews size 并相加,这个方法还是有点复杂
override var intrinsicContentSize: CGSize{
return self.label.intrinsicContentSize + other subviews intrinsicContentSize
}
withAnchor 和 bottomAnchor 约束先创建:
NSLayoutConstraint.activate([
label.leftAnchor.constraint(equalTo: self.leftAnchor),
label.rightAnchor.constraint(equalTo: self.rightAnchor),
label.topAnchor.constraint(equalTo: self.topAnchor),
// 先把自己 withAnchor 和 bottomAnchor 约束写好,外面调用直接指定位置即可
self.widthAnchor.constraint(equalToConstant: 200),
self.bottomAnchor.constraint(equalTo: label.bottomAnchor),
])
这里 View 上有一个 Label,布局时同时把自己的 withAnchor 和 bottomAnchor 写在布局方法里,View 的高度自适应,这样 viewcontroller 指定位置即可
NSLayoutConstraint.activate([
customerView.topAnchor.constraint(equalTo: customerIntrinsicView.bottomAnchor,constant: 80),
customerView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
])

网友评论