How do I set the height of tableHeaderView (UITableView) with autolayout?

后端 未结 12 1271
后悔当初
后悔当初 2020-11-27 10:23

I\'m been smashing my head against the wall with this for last 3 or 4 hours and I can\'t seem to figure it out. I have a UIViewController with a full screen UITableView insi

12条回答
  •  猫巷女王i
    2020-11-27 11:10

    It is quite possible to use generic AutoLayout-based UIView with any AL inner subview structure as a tableHeaderView.

    The only thing one needs is to set a simple tableFooterView before!

    Let self.headerView is some constraint-based UIView.

    - (void)viewDidLoad {
    
        ........................
    
        self.tableView.tableFooterView = [UIView new];
    
        [self.headerView layoutIfNeeded]; // to set initial size
    
        self.tableView.tableHeaderView = self.headerView;
    
        [self.tableView.leadingAnchor constraintEqualToAnchor:self.headerView.leadingAnchor].active = YES;
        [self.tableView.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor].active = YES;
        [self.tableView.topAnchor constraintEqualToAnchor:self.headerView.topAnchor].active = YES;
    
        // and the key constraint
        [self.tableFooterView.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor].active = YES;
    }
    

    If self.headerView changes height under UI rotation one have to implement

    - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator {
        [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    
        [coordinator animateAlongsideTransition: ^(id context) {
            // needed to resize header height
            self.tableView.tableHeaderView = self.headerView;
        } completion: NULL];
    }
    

    One can use ObjC category for this purpose

    @interface UITableView (AMHeaderView)
    - (void)am_insertHeaderView:(UIView *)headerView;
    @end
    
    @implementation UITableView (AMHeaderView)
    
    - (void)am_insertHeaderView:(UIView *)headerView {
    
        NSAssert(self.tableFooterView, @"Need to define tableFooterView first!");
    
        [headerView layoutIfNeeded];
    
        self.tableHeaderView = headerView;
    
        [self.leadingAnchor constraintEqualToAnchor:headerView.leadingAnchor].active = YES;
        [self.trailingAnchor constraintEqualToAnchor:headerView.trailingAnchor].active = YES;
        [self.topAnchor constraintEqualToAnchor:headerView.topAnchor].active = YES;
    
        [self.tableFooterView.trailingAnchor constraintEqualToAnchor:headerView.trailingAnchor].active = YES;
    }
    @end
    

    And also Swift extension

    extension UITableView {
    
        func am_insertHeaderView2(_ headerView: UIView) {
    
            assert(tableFooterView != nil, "Need to define tableFooterView first!")
    
            headerView.layoutIfNeeded()
    
            tableHeaderView = headerView
    
            leadingAnchor.constraint(equalTo: headerView.leadingAnchor).isActive = true
            trailingAnchor.constraint(equalTo: headerView.trailingAnchor).isActive = true
            topAnchor.constraint(equalTo: headerView.topAnchor).isActive = true
    
            tableFooterView?.trailingAnchor.constraint(equalTo: headerView.trailingAnchor).isActive = true
        }
    }
    

提交回复
热议问题