AutoLayout的自适应大小

AutoLayout的自适应大小

问题

近日开发遇到一个需求.如下图:

绿色view为SnapKit代码布局的自定义view,高度固定,宽度根据子视图内容长度而定.右侧label与绿色view间隔为10.

如果不设定绿色view的宽度约束或距父视图右侧约束,xib就会报错,而其宽度又是根据子视图的内容决定的,同时导致右侧label的位置也无法确定.

常用的解决方案可能是先添加上宽度约束,然后在代码里计算绿色view的宽度并更新宽度约束的值.

那么,有什么更好更简单的解决方案呢?

可不可以像UILabel,UIButton,UIImageView这些组件,不指定宽度和高度,自动根据内容计算宽和高呢?

解决方案

其实方法很简单,只需要按照下图操作即可:

Intrinsic Size改为Placeholder.根据下方描述,此处设置的intrinsic content size只会在IB中显示,运行时视图并没有此处设置的intrinsic content size.

注意: view的子视图需要添加距其上下左右的约束,不设置Autolayout无法根据子视图内容自适应宽高

What is intrinsic content size

顾名思义,IntrinsicContentSize-固有内容尺寸.即根据内容计算size,UILabel,UIButton,UIImageView等控件就是系统内部重写了-(CGSize)intrinsicContentSize:方法来实现自适应size的.当view的子视图为这些实现了IntrinsicContentSize的控件时,加上我们添加的固定的left,right,top,bottom约束时,Autolayout就可以根据内容自适应view的大小了.

回到图1,如果绿色view在父视图中非autolayout布局,而是frame布局时,又怎么确定其宽高呢?右侧label又怎么布局呢?

不还是需要根据内容,计算绿色view的子视图的宽度并相加,再加上子视图的间隔吗?

系统在 iOS6 就提供的 API:-systemLayoutSizeFittingSize:,约束添加正确的话,可以直接调用就获取对应的view的宽高,然后更新view的宽高就行

拓展

图1中如果绿色view过长,会将右侧label直接挤掉,如图所示:

此时就需要用到Content Hugging/Content Compression Resistance了.

Content Hugging/Content Compression Resistance都可以设置宽度和高度的优先级.值越大,优先级越高.

Content Hugging抗拉伸约束,如果控件的此属性优先级比另一个控件此属性优先级高的话,那么这个控件就保持不变,另一个可以在需要拉伸的时候拉伸.

Content Compression Resistance抗压缩约束,如果控件的此属性优先级比另一个控件此属性优先级高的话,那么这个控件就保持不变,另一个可以在需要压缩的时候压缩.

设置方式:

IB:

代码:

Objective-C 复制代码
[view setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];

[view setContentCompressionResistancePriority: UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];

如果不想要label被挤掉,只需要将其Content Compression Resistance优先级设置的比绿色view高就行,当绿色view过长,会压缩绿色view的宽度,依然完整显示右侧label.

相关推荐
IT_陈寒11 分钟前
Vite打包时遇到的坑,原来问题出在这里
前端·人工智能·后端
kyriewen17 分钟前
AI生成代码快如闪电,但我修了三个小时——它到底帮了谁?
前端·javascript·ai编程
ayqy贾杰1 小时前
基层管理的三板斧,在AI时代行不通了
前端·后端·团队管理
Apifox1 小时前
Apifox 5 月更新|Postman 导入优化、Runner 支持非 root 运行、请求代码自动带鉴权
前端·后端·安全
miaowmiaow1 小时前
PSD2Code 近期更新与深度解析:从设计稿到生产级代码的完整技术栈
前端·人工智能·ai编程
Hilaku2 小时前
多标签页并发请求导致 Token 刷新失败?只有 15行代码就能解决 !
前端·javascript·程序员
Nile2 小时前
解密Palantir系列一:4. Ontology 不是哲学
开发语言·前端·javascript
因_崔斯汀2 小时前
ECharts 区域地图可视化实战:以山东地图为例
前端
Bacon2 小时前
手摸手带你搞清楚 AI Agent 的六大核心概念
前端·人工智能
王林不想说话2 小时前
TypeScript 进阶知识总结:从 extends、泛型到 infer,一篇打通 TS 类型系统
前端·javascript·typescript