Ok, so I've created a UIView
in interface builder. I'm using AutoLayout
and I've got one subview of this view pinned to all four sides.
Here's what I don't understand. When I load this NIB file using loadNibNamed
. I then get a reference to the view. I set the frame for this view. And yet, when I access the subview (using [containerView viewWithTag:1
]) it's frame hasn't been automatically resized. What gives? If you change the frame for a parent view, why wouldn't the subview frame change as well?
It doesn't make any sense.
Why can't you just load a UIView
, set it's frame and have all the subviews adjust as appropriate (ESPECIALLY since I'm using AutoLayout
!)?
EDIT: To be clear, all I want to do is be able to define a UIView
hierarchy in IB with appropriate AutoLayout
constraints and then be able to load and display that view on the screen sometimes at different sizes? Why is this so hard?
UIKit doesn't update subview geometry immediately when you change a view's geometry. It batches up the updates for efficiency.
After running your event handler, UIKit checks whether any views in the on-screen window hierarchy need to be laid out. If it finds any, it lays them out by solving your layout constraints (if you have any) and then sending layoutSubviews
.
If you want to solve the constraints and lay out a view's subviews immediately, simply send layoutIfNeeded
to the view:
someView.frame = CGRectMake(0, 0, 200, 300);
[someView layoutIfNeeded];
// The frames of someView.subviews are now up-to-date.
I too had the same problem, I was creating a tutorial view where in which I wanted to add multiple UIViews to a scrollview. While I was trying to get the frame from xib, it gave always 320 and because of that the offset for the pages were wrong and my views looked crappy in iPhone6 and 6plus.
I then used pure autolayout approach, ie instead of using the frame, I added constraints through VFL so that subviews fit exactly to the superview. Below is the snapshot of code where I create around 20 UIViews from Xib and add properly to scrollview
Full code here ScrollViewAutolayout
Method to layout the childviews in the scrollview.
@param nil
@result layout the child views
*/
-(void)layoutViews
{
NSMutableString *horizontalString = [NSMutableString string];
// Keep the start of the horizontal constraint
[horizontalString appendString:@"H:|"];
for (int i=0; i<viewsArray.count; i++) {
// Here I am providing the index of the array as the view name key in the dictionary
[viewsDict setObject:viewsArray[i] forKey:[NSString stringWithFormat:@"v%d",i]];
// Since we are having only one view vertically, then we need to add the constraint now itself. Since we need to have fullscreen, we are giving height equal to the superview.
NSString *verticalString = [NSString stringWithFormat:@"V:|[%@(==parent)]|", [NSString stringWithFormat:@"v%d",i]];
// add the constraint
[contentScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:verticalString options:0 metrics:nil views:viewsDict]];
// Since we need to horizontally arrange, we construct a string, with all the views in array looped and here also we have fullwidth of superview.
[horizontalString appendString:[NSString stringWithFormat:@"[%@(==parent)]", [NSString stringWithFormat:@"v%d",i]]];
}
// Close the string with the parent
[horizontalString appendString:@"|"];
// apply the constraint
[contentScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:horizontalString options:0 metrics:nil views:viewsDict]];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With