Setting tableHeaderView height dynamically

后端 未结 8 803
梦如初夏
梦如初夏 2020-12-01 04:16

My application creates a UITableViewController that contains a custom tableHeaderView which may have an arbitrary height. I\'ve been struggling with a way to set this header

相关标签:
8条回答
  • 2020-12-01 05:00

    Just implementing these two UITableView delegate methods worked for me:

    -(CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section
    {
        return 100;
    }
    
    -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
    {
        return UITableViewAutomaticDimension;
    }
    
    0 讨论(0)
  • 2020-12-01 05:01

    Determining the header's frame size using

    header.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
    

    as suggested in the answers above didn't work for me when my header view consisted of a single multiline label. With the label's line break mode set to wrap, the text just gets cut off:

    Instead, what did work for me was using the width of the table view and a height of 0 as the target size:

    header.systemLayoutSizeFitting(CGSize(width: tableView.bounds.width, height: 0))
    

    Putting it all together (I prefer to use an extension):

    extension UITableView {
        func updateHeaderViewHeight() {
            if let header = self.tableHeaderView {
                let newSize = header.systemLayoutSizeFitting(CGSize(width: self.bounds.width, height: 0))
                header.frame.size.height = newSize.height
            }
        }
    }
    

    And call it like so:

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        tableView.updateHeaderViewHeight()
    }
    
    0 讨论(0)
  • 2020-12-01 05:04

    Copied from this post. (Make sure you see it if you're looking for more details)

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
    
        if let headerView = tableView.tableHeaderView {
    
            let height = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
            var headerFrame = headerView.frame
    
            //Comparison necessary to avoid infinite loop
            if height != headerFrame.size.height {
                headerFrame.size.height = height
                headerView.frame = headerFrame
                tableView.tableHeaderView = headerView
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-01 05:06

    Based on @TravMatth and @NSExceptional's answer:

    For Dynamic TableView Header, with multiple line of text(No matter have or not)

    My solution is:

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
    
        if let footView = tableView.tableFooterView {
            let newSize = footView.systemLayoutSizeFitting(CGSize(width: self.view.bounds.width, height: 0))
            if newSize.height != footView.frame.size.height {
                footView.frame.size.height = newSize.height
                tableView.tableFooterView = footView
            }
        }
    }
    

    tableView.tableFooterView = footView to make sure that your tableview Header or Footer updated. And if newSize.height != footView.frame.size.height helps you not to be called this method many times

    0 讨论(0)
  • 2020-12-01 05:14
    **My Working Solution is:
    Add this function in viewcontroller**
    public override func viewDidLayoutSubviews() {
            super.viewDidLayoutSubviews()
            guard let headerView = myTableView.tableHeaderView else { return }
            let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
            var headerFrame = headerView.frame
    
            if height != headerFrame.size.height {
                headerFrame.size.height = height
                headerView.frame = headerFrame
                myTableView.tableHeaderView = headerView
    
                if #available(iOS 9.0, *) {
                    myTableView.layoutIfNeeded()
                }
            }
    
            headerView.translatesAutoresizingMaskIntoConstraints = true
    } 
    
    
     **Add one line in header's view class.**
    override func layoutSubviews() {
            super.layoutSubviews()
            bookingLabel.preferredMaxLayoutWidth = bookingLabel.bounds.width
    
        }
    
    0 讨论(0)
  • 2020-12-01 05:16

    More condensed version of OP's answer, with the benefit of allowing layout to happen naturally (note this solution uses viewWillLayoutSubviews):

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
    
        if let header = tableView.tableHeaderView {
            let newSize = header.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
            header.frame.size.height = newSize.height
        }
    }
    

    Thanks to TravMatth for the original answer.

    0 讨论(0)
提交回复
热议问题