Written on 2025–04–20
在本文當中想要分享一些在 UITableViewCell 當中使用 auto layout 發生的一些事情。
我們都知道在自定義的 UITableViewCell 當中如果想要保有與系統相同的內部間距可以在 auto layout 當中透過 contentView.layoutMarginsGuide
來設定 layout constraint。
當我們想要自定義 cell 並且希望移除系統自帶的分割線同時希望兩個 cell 之間有間距的話就可以採用在 contentView 裡面再包一個 UIView,並且這個 UIView 的 bottomAnchor
與 contentView 有一段距離。
此時如果我們想要在這個當中添加想要的 UIView 並且想要明確給定高度時,我們會直覺的使用以下的 constraint。
NSLayoutConstraint.activate([
subview.topAnchor.constraint(equalTo: view.topAnchor, constant: 12),
subview.leadingAnchor.constraint(equalTo: view.leadingAnchor),
subview.widthAnchor.constraint(equalToConstant: 40),
subview.heightAnchor.constraint(equalToConstant: 40),
subview.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -12)
])
如果依照以上的 constraint 執行,就會直接發生 Encapsulated-Layout-Height
上的錯誤。
這是因為我們指定了 [top, bottom, height] 三個限制,此時 cell 的高度是明確的並且是寫死的,這樣會導致 cell 在創建時系統會先給一個預設的高度時發生錯誤,最終出現 constraint 問題。
正確的作法應該是以下方式。
NSLayoutConstraint.activate([
subview.topAnchor.constraint(equalTo: view.topAnchor, constant: 12),
subview.leadingAnchor.constraint(equalTo: view.leadingAnchor),
subview.widthAnchor.constraint(equalToConstant: 40),
subview.heightAnchor.constraint(equalToConstant: 40),
subview.bottomAnchor.constraint(lessThanOrEqualTo: view.bottomAnchor, constant: -12)
])
最關鍵的地方是在調整 bottomAnchor 的 layout constraint,在這裡我們應該使用 lessThanOrEqualTo
,這樣 cell 的高度在一開始就不會是寫死的,並且會在系統創建 cell 後自動調整高度。