先说一下存在的问题:昨天晚上处理一个相对比较复杂的自适应cell,想缓存获取的高度不对。这里贴一下图。这里这是展示布局上很少的一部分。有时间再研究一下
下面说一下正常情况了。也可能是上面的布局太复杂,哪里出了问题。先展示一下获取正常高度的图
1、先看cell里面的代码;最主要的是看约束,相对cell的top bottom(whiteView),以及whiteView的子视图相对于whiteView的约束
lazy var whiteView:UIView = {
let view = UIView()
view.backgroundColor = .white
view.layer.cornerRadius = 5
view.layer.shadowColor = UIColor.init(hex: "0x3B6FF5").cgColor
view.layer.shadowOffset = CGSize(width: 0, height: 0)
view.layer.shadowRadius = 5
view.layer.shadowOpacity = 0.8
return view
}()
lazy var titleLabel: UILabel = {
let view = UILabel()
view.text = "描述标题描述标题描述标题描述标题描述标题描述标题描述标题描述标题描述标题描述标题描述标题描述标题描述标题描述标题描述标题描述标题"
view.numberOfLines = 0
view.font = .systemFont(ofSize: 14)
view.sizeToFit()
return view
}()
lazy var picImageView: UIImageView = {
let view = UIImageView()
view.image = UIImage.image(image: UIImage.init(named: "001")!, orientation: .up)
return view
}()
lazy var commentView:ALFitHeightView = {
let view = ALFitHeightView()
return view
}()
func al_makeUI(){
self.contentView.addSubview(self.whiteView)
self.whiteView.addSubview(self.titleLabel)
self.whiteView.addSubview(self.picImageView)
self.whiteView.addSubview(self.commentView)
self.titleLabel.snp.makeConstraints { (make) in
make.leading.top.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
}
self.picImageView.snp.makeConstraints { (make) in
make.leading.equalTo(self.titleLabel)
make.right.equalTo(self.titleLabel)
// make.center.equalToSuperview()
make.top.equalTo(self.titleLabel.snp.bottom).offset(5)
}
self.commentView.snp.makeConstraints { (make) in
make.top.equalTo(self.picImageView.snp.bottom).offset(5)
make.left.equalTo(self.titleLabel.snp.left)
make.right.equalTo(self.titleLabel.snp.right)
make.bottom.equalToSuperview().offset(-15)
}
self.whiteView.snp.makeConstraints { (make) in
make.top.left.equalToSuperview().offset(10)
make.bottom.right.equalToSuperview().offset(-10)
}
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.selectionStyle = .none
al_makeUI()
}
2、看控制器里面的代码
var heightArr:NSMutableArray = {
let arr = NSMutableArray()
return arr
}()
lazy var tableView: UITableView = {
let view = UITableView.init(frame: CGRect(x: 0, y: CGFloat(NavigationHeight), width: self.view.frame.size.width, height: self.view.frame.size.height - CGFloat(NavigationHeight)), style: .plain)
view.delegate = self
view.dataSource = self
view.separatorStyle = .none
view.register(ALFitHeightTableViewCell.self, forCellReuseIdentifier: "cell")
view.tableFooterView = UIView.init(frame: CGRect.zero)
view.backgroundColor = UIColor.init(hex: "FAFBFF")
if #available(iOS 11, *){
view.contentInsetAdjustmentBehavior = .never
}else{
if #available(iOS 13.0, *) {
view.automaticallyAdjustsScrollIndicatorInsets = false
} else {
self.automaticallyAdjustsScrollViewInsets = false
}
}
return view
}()
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 30
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if self.heightArr.count > 0 {
let height = self.heightArr[safe:indexPath.row]
if height != nil {
DebugLog("1111")
return height as! CGFloat
}
return UITableView.automaticDimension
// return height != nil ? height as! CGFloat : UITableView.automaticDimension
}else{
return UITableView.automaticDimension
}
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ALFitHeightTableViewCell
return cell
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let height = self.heightArr[safe:indexPath.row]
if height == nil{
let height = cell.systemLayoutSizeFitting(CGSize(width: self.tableView.width(), height: 0), withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel).height
self.heightArr.add(height)
DebugLog(height)
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
self.navTitle = "tableviewcell高度自适应"
self.view.addSubview(self.tableView)
}
补充:经一朋友提醒,试了一下 func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 在这个方法里面可以直接拿到cell.frame,可以不用再调用系统的systemLayoutSizeFitting方法再计算一遍消耗CPU资源