Is it possible to use AutoLayout with UITableView's tableHeaderView?

前端 未结 29 1344
醉梦人生
醉梦人生 2020-11-28 19:51

Since I discovered AutoLayout I use it everywhere, now I\'m trying to use it with a tableHeaderView.

I made a subclass of

29条回答
  •  渐次进展
    2020-11-28 20:38

    I was able to achieve it by the following approach (this works for footer the same way).

    First, you will need small UITableView extension:

    Swift 3

    extension UITableView {
        fileprivate func adjustHeaderHeight() {
            if let header = self.tableHeaderView {
                adjustFrame(header)
            }
        }
    
        private func adjustFrame(_ view: UIView) {
            view.frame.size.height = calculatedViewHeight(view)
        }
    
        fileprivate func calculatedHeightForHeader() -> CGFloat {
            if let header = self.tableHeaderView {
                return calculatedViewHeight(header)
            }
            return 0.0
        }
    
        private func calculatedViewHeight(_ view: UIView) -> CGFloat {
            view.setNeedsLayout()
            let height = view.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
            return height
        }
    }
    

    In your view controller class implementation:

    // this is a UIView subclass with autolayout
    private var headerView = MyHeaderView()
    
    override func loadView() {
        super.loadView()
        // ...
        self.tableView.tableHeaderView = headerView
        self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension
        // ...
    }
    
    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
    
        // this is to prevent recursive layout calls
        let requiredHeaderHeight = self.tableView.calculatedHeightForHeader()
        if self.headerView.frame.height != requiredHeaderHeight {
            self.tableView.adjustHeaderHeight()
        }
    }
    

    Notes about a header UIView's subview implementation:

    1. You have to 100% sure that your header view has the correct autolayout setup. I would recommend to start with simple header view with just one heigh constraint and try out the setup above.

    2. Override requiresConstraintBasedLayout and return true:

    .

    class MyHeaderView: UIView {
       // ...
       override static var requiresConstraintBasedLayout : Bool {
           return true
       }
       // ...
    }
    

提交回复
热议问题