AutoLayout的自適應(yīng)大小

AutoLayout的自適應(yīng)大小

問(wèn)題

近日開(kāi)發(fā)遇到一個(gè)需求.如下圖:

圖1

綠色view為SnapKit代碼布局的自定義view,高度固定,寬度根據(jù)子視圖內(nèi)容長(zhǎng)度而定.右側(cè)label與綠色view間隔為10.

如果不設(shè)定綠色view的寬度約束或距父視圖右側(cè)約束,xib就會(huì)報(bào)錯(cuò),而其寬度又是根據(jù)子視圖的內(nèi)容決定的,同時(shí)導(dǎo)致右側(cè)label的位置也無(wú)法確定.

常用的解決方案可能是先添加上寬度約束,然后在代碼里計(jì)算綠色view的寬度并更新寬度約束的值.

那么,有什么更好更簡(jiǎn)單的解決方案呢?

可不可以像UILabel,UIButton,UIImageView這些組件,不指定寬度和高度,自動(dòng)根據(jù)內(nèi)容計(jì)算寬和高呢?

解決方案

其實(shí)方法很簡(jiǎn)單,只需要按照下圖操作即可:

圖2

Intrinsic Size改為Placeholder.根據(jù)下方描述,此處設(shè)置的intrinsic content size只會(huì)在IB中顯示,運(yùn)行時(shí)視圖并沒(méi)有此處設(shè)置的intrinsic content size.

注意: view的子視圖需要添加距其上下左右的約束,不設(shè)置Autolayout無(wú)法根據(jù)子視圖內(nèi)容自適應(yīng)寬高

What is intrinsic content size

顧名思義,IntrinsicContentSize-固有內(nèi)容尺寸.即根據(jù)內(nèi)容計(jì)算size,UILabel,UIButton,UIImageView等控件就是系統(tǒng)內(nèi)部重寫(xiě)了-(CGSize)intrinsicContentSize:方法來(lái)實(shí)現(xiàn)自適應(yīng)size的.當(dāng)view的子視圖為這些實(shí)現(xiàn)了IntrinsicContentSize的控件時(shí),加上我們添加的固定的left,right,top,bottom約束時(shí),Autolayout就可以根據(jù)內(nèi)容自適應(yīng)view的大小了.

回到圖1,如果綠色view在父視圖中非autolayout布局,而是frame布局時(shí),又怎么確定其寬高呢?右側(cè)label又怎么布局呢?

不還是需要根據(jù)內(nèi)容,計(jì)算綠色view的子視圖的寬度并相加,再加上子視圖的間隔嗎?

系統(tǒng)在 iOS6 就提供的 API:-systemLayoutSizeFittingSize:,約束添加正確的話,可以直接調(diào)用就獲取對(duì)應(yīng)的view的寬高,然后更新view的寬高就行

拓展

圖1中如果綠色view過(guò)長(zhǎng),會(huì)將右側(cè)label直接擠掉,如圖所示:

圖3

此時(shí)就需要用到Content Hugging/Content Compression Resistance了.

Content Hugging/Content Compression Resistance都可以設(shè)置寬度和高度的優(yōu)先級(jí).值越大,優(yōu)先級(jí)越高.

Content Hugging抗拉伸約束,如果控件的此屬性優(yōu)先級(jí)比另一個(gè)控件此屬性優(yōu)先級(jí)高的話,那么這個(gè)控件就保持不變,另一個(gè)可以在需要拉伸的時(shí)候拉伸.

Content Compression Resistance抗壓縮約束,如果控件的此屬性優(yōu)先級(jí)比另一個(gè)控件此屬性優(yōu)先級(jí)高的話,那么這個(gè)控件就保持不變,另一個(gè)可以在需要壓縮的時(shí)候壓縮.

設(shè)置方式:

IB:

截屏2021-06-29 上午11.55.32

代碼:

[view setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];
[view setContentCompressionResistancePriority: UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];

如果不想要label被擠掉,只需要將其Content Compression Resistance優(yōu)先級(jí)設(shè)置的比綠色view高就行,當(dāng)綠色view過(guò)長(zhǎng),會(huì)壓縮綠色view的寬度,依然完整顯示右側(cè)label.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容