Auto Layout for tableHeaderView

2019-05-14 06:36发布

I've been trying to improve my layout techniques by learning Auto Layout, but I've stumbled across an issue that I just haven't been able to solve.

Here's what happens: there's a view controller containing, among other things, a UITableView and a UIView. This view is placed just below the table view, and its height does not extend to the full screen height (let's say it takes up the top half of it).

The table view, using a grouped style and placed just above the mentioned view, has a translucent background, so that you can actually see the contents of the view just below it. Since the view takes up half of the screen, though, I need to add a tableHeaderView (also translucent) to this table view in order for the whole background content to be clearly visible when first loading the view controller.

The final effect of this would be like a fixed tableHeaderView that disappears on the background when scrolling up the table view.

This is done in a simple way using springs and struts, but Auto Layout crashes the app every time I try to add the header to the table view (no matter how I do it).

Since I'm looking for a way to always match the view height in the background (otherView) with the tableHeaderView height, I'm using:

[self.view addConstraint:[NSLayoutConstraints constraintWithItem:headerView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:otherView attribute:NSLayoutAttributeHeight multiplier: 1 constant:0]];

(it is my understanding that the constraint can't be added directly to the table view, since otherView is not a child of it)

and also:

[headerView setTranslatesAutoResizingMaskIntoConstraints:NO]

These calls always result in this crash:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super.'

So is there any way to do this? Is it possible to actually tie a tableHeaderView height to another element on the view using Auto Layout?

I should also note that I've long moved away from IB, so this all done purely in code, specifically on loadView.

1条回答
我命由我不由天
2楼-- · 2019-05-14 07:27

If you make a instance variable for the NSLayoutConstraint and set it like so:

headerViewHeightConstraint = [NSLayoutConstraint constraintWithItem:headerView
                                                          attribute:NSLayoutAttributeHeight
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:nil
                                                          attribute:NSLayoutAttributeNotAnAttribute
                                                         multiplier:1.0f
                                                           constant:otherView.frame.size.height];

You can resize it by:

headerViewHeightConstraint.constant = 1000.0f;
[headerView updateConstraintsIfNeeded];

P.S: keep in mind that addConstraints: is not the same thing as addConstraint:.

addConstraints is used in conjunction with an array of constraints or [NSLayoutConstraints constraintsWithVisualFormat:...]

addConstraint: is used in conjunction with a single constraint which is the example above.

If you're overriding layoutSubviews: call [super layoutSubviews] in its very first line. That forces the view and its subviews to layout themselves so you can access their frame details etc.

查看更多
登录 后发表回答