iOS Snpkit、Masonry与tableHeaderView布局解决方案

一个UITableView头部添加一个UIView,都用snpkit(Swift代码)布局,一般代码写法

  override func viewDidLoad() {
       super.viewDidLoad()
        self.view.addSubview(listView)
        listView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }

        listView.tableHeaderView = headBackView
        headBackView.snp.makeConstraints { make in
            make.width.equalTo(listView.snp.width)
            make.height.equalTo(100)
        }
  }
1

很明显,view遮住了cell,原因是:

  • 在viewDidLoad中,listView添加headerView时,headBackView的frame并没有生成,listView.tableHeaderView高度为0
  • 后面刷新布局时,headBackView高度改变已经不能影响listView.tableHeaderView的布局了
  • 因此,需要线确定headBackView的frame,再给listView.tableHeaderView赋值
    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.addSubview(headBackView)
        headBackView.snp.makeConstraints { make in
            make.top.left.right.equalToSuperview()
            make.height.equalTo(100)
        }

        self.view.addSubview(listView)
        listView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
  }

// 在布局完成后的方法中,再操作
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        if listView.tableHeaderView == nil {
            headBackView.removeFromSuperview()
            listView.tableHeaderView = headBackView
            headBackView.snp.remakeConstraints { make in
                make.width.equalTo(listView.snp.width)
                make.height.equalTo(100)
            }
        }
    }
2

在某个时间点,头部view高度变化

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        if listView.tableHeaderView == nil {
            headBackView.removeFromSuperview()
            listView.tableHeaderView = headBackView
            headBackView.snp.remakeConstraints { make in
                make.width.equalTo(listView.snp.width)
                make.height.equalTo(100)
            }

            DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                self.headBackView.snp.updateConstraints { make in
                    make.height.equalTo(200)
                }
            }
        }
    }

3

view还是遮挡了listView,但现在istView.tableHeaderView的高度有100,也就是说:listView.tableHeaderView被赋值后,snpkit不能在改变它的布局
headView发生高度变化时,只能先取消istView.tableHeaderView赋值,添加到self.view中,更改布局,再赋值给istView.tableHeaderView

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        if listView.tableHeaderView == nil {
            headBackView.removeFromSuperview()
            listView.tableHeaderView = headBackView
            headBackView.snp.remakeConstraints { make in
                make.width.equalTo(listView.snp.width)
                make.height.equalTo(100)
            }

            DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                self.listView.tableHeaderView = nil
                self.view.addSubview(self.headBackView)
                self.headBackView.snp.remakeConstraints { make in
                    make.width.equalTo(0)
                    make.height.equalTo(300)
                }

                // 添加一个延时,再去刷新
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.001) {
                    self.headBackView.removeFromSuperview()
                    self.listView.tableHeaderView = self.headBackView
                    self.headBackView.snp.remakeConstraints { make in
                        make.width.equalTo(self.listView.snp.width)
                        make.height.equalTo(300)
                    }
                }
            }
        }
    }
4

你可能感兴趣的:(iOS Snpkit、Masonry与tableHeaderView布局解决方案)