0

I created a custom container viewController by using the parent-child model. In the parent I create the child as follows:

 // Show Friends view of childs' controller AddFriendViewController
    self.friendVC = [[AddFriendViewController alloc] init];
    [self addChildViewController:self.friendVC];
    self.friendVC.view.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
    [self.view addSubview:self.friendVC.view];
    [self.friendVC didMoveToParentViewController:self];

And then in the child's (frienVC) "loadView" I initialized the child's view as follows , and also create a UIView (topBarView) that I will display on the child VC:

- (void)loadView {
    self.view = [[UIView alloc]init];
    self.view.backgroundColor = [UIColor colorWithHex:SCREEN_ADDFRIENDVIEWCONTROLLER_COLOR];

    // Create topBar view
    self.topBarView = [[UIView alloc] init];
    [self.containerView addSubview:self.topBarView];
}

Now, I am using auto layout constraints to position the "topBarView" in the child's view. And I noticed something really weird. In the " updateViewConstraints " where I set the position and size of the "topBarView" , the frame of the child's view is (0,0,320,568), which is exactly correct. But in the " viewDidAppear: " method, which gets called AFTER the " updateViewConstraints " method, the child's view frame got suddenly changed to (284,160,0,0), which is a TOTALLY random frame.

Why is the system setting the frame of the child's view frame to this after the updateViewConstraints method was called?

Pang
  • 9,564
  • 146
  • 81
  • 122
malena
  • 798
  • 11
  • 26

1 Answers1

0

I found the issue. It looks like setting the "frame" for the childViewController's view is not a safe way to set the child's view position and size, because it gets reset by the system if constraints are used in the child vc to set place other views inside it. For some reason, the "frame" gets reset to some random frame with 0 width and 0 height in the child view controller, and thus the child vc view never shows up. I found through trial and error that sticking to using constraints for setting all the position and sizes of UIViews works. So instead of setting the "frame" of the child view controller in the parent view controller, I use constraints as follows:

    self.friendVC = [[AddFriendViewController alloc] init];

    [self addChildViewController:self.friendVC];
    [self.view addSubview:self.friendVC.view];
    [self.view setTranslatesAutoresizingMaskIntoConstraints:NO];

    NSDictionary *viewsDictionary = @{ @"cview":self.self.friendVC.view};

    [self.view addConstraints:[NSLayoutConstraint
                               constraintsWithVisualFormat:@"H:|[cview]|"
                               options:0 metrics:nil
                               views:viewsDictionary]];
    [self.view addConstraints:[NSLayoutConstraint
                               constraintsWithVisualFormat:@"V:|[cview]|"
                               options:0 metrics:nil
                               views:viewsDictionary]];

    [self.friendVC didMoveToParentViewController:self];

Then in the child vc in loadView method, I just allocate memory and initialize the view. There is no need to set the size of the child's view here because that is what the parent does with the constraints. Autoresizing needs to also be turned off for the Child's view and all other views inside it.

(void)loadView {
self.view = [[UIView alloc]init];
self.view.backgroundColor = [UIColor 
colorWithHex:SCREEN_ADDFRIENDVIEWCONTROLLER_COLOR];

[self.view setTranslatesAutoresizingMaskIntoConstraints:NO];

Then in "viewDidAppear", once the child's view has loaded and appeared, it is a good point to add the additional UIViews within the child's view, again using constraints instead of setting "frames".

- (void)viewDidAppear:(BOOL)animated {

//Add topBarView constraints

self.topBarView = [[UIView alloc] init];
[self.view addSubview:self.topBarView];
[self.topBarView setTranslatesAutoresizingMaskIntoConstraints:NO];

NSDictionary *viewsDictionary = @{ @"topBarView":self.topBarView};

NSDictionary *metrics = @{@"topBarHeight":[NSNumber numberWithFloat:SCREEN_ADDFRIENDVC_TOPBAR_HEIGHT]};


NSArray *topBarView_V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topBarView(==topBarHeight)]" options:0 metrics:metrics views:viewsDictionary];

NSArray *topBarView_H = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[topBarView]|" options:0 metrics:metrics views:viewsDictionary];

[self.view addConstraints:topBarView_V];
[self.view addConstraints:topBarView_H];




self.topBarView.backgroundColor = [UIColor colorWithHex:SCREEN_ADDFRIENDVC_TOPBAR_COLOR];

And this worked for me. So at the outset the main learning is not to mix setting "frames" with "constraints" and just stick to constraints basically.

malena
  • 798
  • 11
  • 26