tableHeaderView自動布局技巧

前言

UITableView的有一個tableHeaderView屬性:整體列表的頭部,滾動的時候回跟隨列表整體一起滾動。
常規(guī)設置tableHeaderView會給定一個UIView再去設定frame,一旦是動態(tài)布局還得計算個別動態(tài)控件的高度,再將tableHeaderView的height更新,及其麻煩。
因此用動態(tài)布局設定headerView不香么?

動態(tài)布局設定tableHeaderView

先來看看效果


演示

上邊這個效果就是拿定義的View嵌入到tableView的tableHeaderView中做到的。

完整代碼:

import UIKit
import SnapKit
class ViewController: UIViewController{
   
    
    let headerView = TestHeaderView(frame: .zero)
    let tableView : UITableView = UITableView(frame: .zero, style: .plain)
    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(tableView)
        tableView.translatesAutoresizingMaskIntoConstraints = false
        
        tableView.separatorStyle = .none //隱藏tableview分割線
        //把 autoresizingMask 轉換為 Constraints,我們要用自動因此設置為false,不加會警告
        tableView.snp.makeConstraints { (make) in
            make.edges.equalToSuperview().offset(0)
        }
        tableView.tableHeaderView = headerView//相當于 addsubview
        
        headerView.backgroundColor  = .lightGray
        
        headerView.updateBlock = {[weak self] in
            self?.headerView.layoutIfNeeded()
            self?.tableView.tableHeaderView?.layoutIfNeeded()
        }

        headerView.snp.makeConstraints { (make) in
            make.left.top.equalToSuperview()
            make.width.equalTo(UIScreen.main.bounds.width)//
            //height 動態(tài)嵌入 不用獲取
        }
        
        headerView.loadData()
    }

}

extension TestHeaderView {
    func loadData() {
        header.backgroundColor = .red
        content.numberOfLines = 0
        content.text = "是打算打算打算大薩達撒大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打所多所打算大薩達撒大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打所多所打算大薩達撒大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打所多所打算大薩達撒大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打所多所打算大薩達撒大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打所多所打算大薩達撒大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打所多所打算大薩達撒大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打所多所打算大薩達撒大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打所多所打算大薩達撒大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打所多所打算大薩達撒大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打大家快來薩達所打所多所打算大薩達撒大家快來薩達所打大家快所打大家快"
        title.text = "撒大聲地計算的撒大聲地"
        
        if let tmpUpdateBlock = self.updateBlock {
            tmpUpdateBlock()
        }
    }
}
class TestHeaderView: UIView {
    private let header =  UIImageView()
    private let title = UILabel()
    private let content = UILabel()
    private let bottomLine = UIView()
    typealias UpdateHeightBlock = ()->();
    var updateBlock:UpdateHeightBlock?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    func setupUI() {
        self.addSubview(header)
        self.addSubview(title)
        self.addSubview(content)
        self.addSubview(bottomLine)
        
        title.backgroundColor = .green
        content.backgroundColor = .red
        header.layer.cornerRadius = 14
        header.layer.masksToBounds = true
        header.isUserInteractionEnabled = true
        //            header.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(headerClick)))
        bottomLine.backgroundColor = .darkGray
        header.snp.makeConstraints { (make) in
            make.left.top.equalTo(15)
            make.size.equalTo(28)
            
        }
        title.snp.makeConstraints { (make) in
            make.centerY.equalTo(header.snp.centerY)
            make.left.equalTo(header.snp.right).offset(5)
            make.right.equalTo(-15)
        }
        content.snp.makeConstraints { (make) in
            make.top.equalTo(header.snp.bottom)
            make.left.equalTo(title)
            make.right.equalTo(title)
        }
  
        bottomLine.snp.makeConstraints { (make) in
            make.left.equalTo(15)
            make.right.equalTo(title)
            make.top.equalTo(content.snp.bottom).offset(10)
            make.height.equalTo(5)
            make.bottom.equalToSuperview()
        }
    }
}

非常簡單的實現(xiàn)代碼核心就是在TestHeader類中聲明一個閉包,當loadData布局后,通過controller層將headerView和tableView 使用layoutIfNeeded()更新布局即可。
核心代碼:

headerView.updateBlock = {[weak self] in
            self?.headerView.layoutIfNeeded()
            self?.tableView.tableHeaderView?.layoutIfNeeded()
        }

如果我們在工期緊的時候需要做這種動態(tài)布局的復雜頁面,可以將tableView的tableHeader作為我們的視圖容器,contentSize,約束,tableview內部會全部計算好。肯定是比scrollView省勁的。

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

相關閱讀更多精彩內容

友情鏈接更多精彩內容