My goal:
I'm trying to find a general recipe how to add views that I created in Interface Builder to a parent view that I create in Interface Builder as well, while letting their layout constraints determine the size of their respective parent views.
The key idea is to get cascading views with a variable size. A view should first determine its own size by resolving its layout constraints. Once it's done it has a fixed size from its superview's perspective so now the superview can determine its size by resolving its own layout constraints and so on.
My approach:
I create a new XIB file in Xcode and open it in Interface Builder. Next, I drag another UIView
from the Object library to the XIB's view in order to add it as a subview. Using layout constraints I pin all four sides of the subview to its superview's edges:
Now I create another XIB file which is supposed to be the subview. I drag a UILabel
and a UIButton
to its view. I give the button a fixed height constraint and add more constraints to pin the label and the button to the view's edges:
Now comes the tricky part that I haven't been able to solve yet:
I couldn't find any way to add the view of this second XIB file to the subView of the first XIB using only Interface Builder (is this even possible?) so I tried it by writing some code. I created a UIView
custom class and set the class value in Interface Builder accordingly. In the custom class I added this method:
- (void)awakeFromNib {
UIView *view = [[[NSBundle mainBundle] loadNibNamed:@"DynamicSubView" owner:self options:nil] objectAtIndex:0];
[self.subView addSubview:view];
view.translatesAutoresizingMaskIntoConstraints = NO;
[self addConstraintsForView:view];
}
- (void)addConstraintsForView:(UIView *)view {
[self addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.subView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.subView attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.subView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.subView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0]];
}
The method addLayoutConstraintsForView:
adds constraints to the view from the second XIB that pins all its four edges to the subView's edges. Now the subView should resize dynamically with the view it contains. However, it doesn't seem to work. Any idea or a good recipe how to deal with this?
Remark: The top most view here is intended to be a UITableViewCell
. I want it to layout itself and pass its height to its tableView
using the method introduced here.