本文以UITableView 使用SnapKit 來設(shè)置約束為例:
1. 列表頁設(shè)置高度自適應(yīng)、預(yù)估行高
// 自動(dòng)計(jì)算行高
tableView.rowHeight = UITableView.automaticDimension
// 設(shè)置預(yù)估行高, 必須要寫, 否則打印垃圾log日志, 提示約束沖突
tableView.estimatedRowHeight = 400
2. cell 中的操作
- 一般情況下只根據(jù)字體的多少, 自動(dòng)換行后計(jì)算承載文字的控件底部約束與contentView 進(jìn)行約束更新即可.
- 這里說另一種情況, 根據(jù)數(shù)據(jù)的不同, cell會(huì)顯示不同數(shù)量的子控件, 也就是說, 子控件或者子控件和contentView 的相對(duì)約束發(fā)生改變時(shí)要做的處理.
- 布局時(shí)當(dāng)前后約束參照物發(fā)生改變時(shí), 一般都選擇記錄約束 -> 卸載約束 -> 重新設(shè)置約束來約束布局; 而當(dāng)參照物未發(fā)生改變(也就是上面說的一把情況)的時(shí)候, 只需要更新約束即可.
示例圖片image.png
2.1 聲明需要記錄的約束
// MARK: 記錄底部視圖的 頂部約束 (需要引入import SnapKit)
var bottomViewTopConstraint: Constraint?
2.2 記錄約束
// MARK: cell 自適應(yīng)高度, 需要與底部視圖做約束(具體??)
contentView.addSubview(bottomView)
bottomView.snp_makeConstraints { (make) in
make.left.right.equalTo(contentView)
// MARK: 記錄底部視圖的 頂部約束的賦值方式 (retweetView 就是可有可無的view, 根據(jù)數(shù)據(jù)來判斷顯示還是隱藏, 所以要記錄bottomView 的頂部約束)
bottomViewTopConstraint = make.top.equalTo(retweetView.snp_bottom).constraint
make.height.equalTo(35)
/** swift3.0 之后cell 的高度自適應(yīng)
寫法1 - 直接設(shè)置最底部控件的底部與contentView的底部平齊
*/
make.bottom.equalTo(contentView)
}
2.3 在得到數(shù)據(jù)時(shí)先卸載記錄的約束
// MARK: - 注意: 每次重新對(duì)底部視圖的頂部做約束時(shí), 要把以前對(duì)底部視圖的頂部的約束移除 ->卸載約束!
bottomViewTopConstraint?.deactivate()
2.4 重新設(shè)置約束
if 顯示retweetView {
retweetView.isHidden = false
bottomView.snp_makeConstraints { (make) in
// 由于cell 的緩存機(jī)制, 不知道從緩存池拿出來的約束是哪個(gè)樣子的, 所以都加上記錄. 方便下次進(jìn)來的時(shí)候卸載.
bottomViewTopConstraint = make.top.equalTo(retweetView.snp_bottom).constraint
}
} else {
// originalView 是retweetView 同級(jí)的且在retweetView 位置之上的view
retweetView.isHidden = true
bottomView.snp_makeConstraints { (make) in
bottomViewTopConstraint = make.top.equalTo(originalView.snp_bottom).constraint
}
}
拓展: cell 的高度自適應(yīng)寫法
// MARK: cell 自適應(yīng)高度, 需要與底部視圖做約束(具體??)
contentView.addSubview(bottomView)
bottomView.snp_makeConstraints { (make) in
make.left.right.equalTo(contentView)
// MARK: 記錄底部視圖的 頂部約束的賦值方式
bottomViewTopConstraint = make.top.equalTo(retweetView.snp_bottom).constraint
make.height.equalTo(35)
/** swift3.0 之后cell 的高度自適應(yīng)
寫法1 - 直接設(shè)置最底部控件的底部與contentView的底部平齊
*/
make.bottom.equalTo(contentView)
}
// swift3.0 之前通過這種方式來約束
// contentView.snp_makeConstraints { (make) in
// make.bottom.equalTo(bottomView)
// }
/** swift3.0 之后cell 的高度自適應(yīng)
寫法2 - 設(shè)置contentView 的四邊與self 相等, 底部與最底部控件平齊
弊端: 控制臺(tái)會(huì)打印約束的垃圾信息.
Changing the translatesAutoresizingMaskIntoConstraints property of the contentView of a UITableViewCell is not supported and will result in undefined behavior, as this property is managed by the owning UITableViewCell
(不支持更改UITableViewCell的contentView的translatesAutoresizingMaskIntoConstraints屬性,這將導(dǎo)致未定義的行為,因?yàn)榇藢傩杂伤鶎賃ITableViewCell管理)
*/
// contentView.snp_makeConstraints { (make) in
// make.left.top.right.bottom.equalTo(self)
// make.bottom.equalTo(bottomView)
// }
.End
