Loaded UIView from NIB - wrong frame size

So, I created the UIView constructor in the interface. I use AutoLayout , and I have one view of this view attached to all four sides.

Thatโ€™s what I donโ€™t understand. When I load this NIB file using loadNibNamed . Then I get a link to the view. I set the frame for this view. And yet, when I access the subview (using [ containerView viewWithTag:1 ]), it was not automatically changed. What gives? If you change the frame for the parent view, why not the subtask frame?

That doesn't make any sense.

Why can't you just download the UIView , set its frame and configure all the subzones accordingly (ESPECIALLY, since I use AutoLayout !)?

EDIT. To be clear, all I want to do is define a UIView hierarchy in IB with the appropriate AutoLayout restrictions, and then be able to load and display this view on the screen, sometimes of different sizes? Why is it so hard?

+7
ios
source share
3 answers

UIKit does not update the subview geometry immediately when the view geometry changes. It updates efficiency for efficiency.

After starting the event handler, UIKit checks whether any views in the window hierarchy should be scheduled. If he finds something, he will lay them out, resolving your layout constraints (if any), and then send layoutSubviews .

If you want to immediately remove the restrictions and lay out the view as views, just send layoutIfNeeded to the view:

 someView.frame = CGRectMake(0, 0, 200, 300); [someView layoutIfNeeded]; // The frames of someView.subviews are now up-to-date. 
+11
source share

I had the same problem too, I was creating a tutorial view in which I wanted to add several UIViews to scrollview. While I was trying to get the frame from xib, it always gave 320, and because of this, the page offset was wrong, and my views looked crap on the iPhone6 โ€‹โ€‹and 6plus.

Then I used a clean approach to auto-detection, i.e. instead of using a frame, I added restrictions via VFL so that subviews exactly match the supervisor. Below is a snapshot of the code in which I create about 20 UIViews from Xib and correctly add 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]]; } 
+1
source share

Unfortunately, Rob's accepted answer didn't work for me. Here's what worked:

 - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"myXib" owner:self options:nil]; [self addSubview:views[0]]; self.subviews[0].frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); //ADDED THIS FOR PROPER SIZE } return self; } 
0
source share

All Articles