小心使用cell的contentView

小心使用cell的contentView

UITableViewCell是每個(gè)iOS開(kāi)發(fā)者都必須掌握的。我們都知道,應(yīng)當(dāng)將子視圖加入其contentView,而非cell本身。但為什么這樣做,如果不這樣做有什么后果,你知道嗎?

最近在開(kāi)發(fā)中遇到一個(gè)問(wèn)題:使用contentView做insets效果時(shí),Auto Layout產(chǎn)生沖突。

起因源于需要實(shí)現(xiàn)這種效果:

圖1

即內(nèi)容與cell四邊保持距離,可以用UIEdgeInsets表示。根據(jù)以往經(jīng)驗(yàn),既然所有子視圖都被加入contentView,那么使用它做insets再合適不過(guò)了。代碼如下:

contentView.snp.makeConstraints { (make) in
    make.edges.equalToSuperview().inset(UIEdgeInsets(top: 10.0, left: 5.0, bottom: 10.0, right: 5.0))
}

但運(yùn)行后的效果卻不是我們想要的:

圖2

查看console中出現(xiàn)錯(cuò)誤信息,提示布局沖突(這里我使用self-sizing cell,即cell的高度由Auto Layout自動(dòng)計(jì)算):

圖3

仔細(xì)觀察,可以發(fā)現(xiàn):UIView-Encapsulated-Layout-Height這條約束與cell的總體高度(20.0 + label高度 + 20.0)沖突,系統(tǒng)選擇打破底部約束。從字面意思來(lái)看,前者似乎也在定義cell高度。而且,經(jīng)過(guò)Google,發(fā)現(xiàn)這條約束由系統(tǒng)設(shè)置,優(yōu)先級(jí)為required,無(wú)法降級(jí)。

網(wǎng)上給出的說(shuō)法是將我們自己的約束降級(jí),避免沖突。但這種做法不符合需求:UIView-Encapsulated-Layout-Height這條約束所定義的cell高度不是我們想要的。那么,到底是哪里出了問(wèn)題呢?

經(jīng)過(guò)反復(fù)測(cè)試,終于發(fā)現(xiàn)問(wèn)題所在:只要不使用contentView做insets,就一切安好。那么,為什么不能呢?帶著強(qiáng)烈的好奇心,我翻閱文檔。文檔對(duì)于contentView的解釋是這樣的:

圖4

要點(diǎn)如下:

  1. cell子視圖必須加入contentView;
  2. 之所以必須加入contentView,是因?yàn)樵诰庉嬆J较?,cell會(huì)操作contentView。如下圖所示:
圖6

此外,還在大片的錯(cuò)誤信息中發(fā)現(xiàn)了一段非常不起眼提示:

圖5

大意為:不要修改contentView屬性translatesAutoresizingMaskIntoConstraints,否則后果自負(fù)??。

SnapKit會(huì)自動(dòng)修改視圖的這個(gè)屬性(false),怪不得會(huì)觸發(fā)這個(gè)警告。

結(jié)論

經(jīng)過(guò)上面的思考,可以得出結(jié)論:

  1. 子視圖都必須加入contentView
  2. 不要修改contentView的布局屬性,frame也好,添加約束也好,都是禁止的。

可能有人會(huì)問(wèn),這樣的話(huà)如何實(shí)現(xiàn)insets效果呢?答案很簡(jiǎn)單:創(chuàng)建一個(gè)containerView,將所有子視圖放到里面,然后把它加入contentView,再做insets。例如:

圖7
?著作權(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)容