Search code examples
iosobjective-cnslayoutconstraint

updateViewConstraints gives "Impossible to set up layout with view hierarchy unprepared for constraint"


I have a View Controller that inits a child View Controller in ViewDidLoad.

- (void)viewDidLoad {
    mapVC = [[CollectionMapViewController alloc] init];
}

It then adds this VC as a subview in an IBAction method:

- (IBAction)left_seg1:(id)sender {                
            [mapVC layoutMapView];
            [self.view addSubview:mapVC.view];
            NSLog(@"num 1");
            _tagTwo = 3;
            return;
}

I am trying to create constraints for the subview with respect to its parent view. In my attempt to do so, I have added updateViewConstraints to the parent class.

- (void)updateViewConstraints{
    self.view.translatesAutoresizingMaskIntoConstraints = NO;
    mapVC.view.translatesAutoresizingMaskIntoConstraints = NO;

    NSLayoutConstraint* trailConstrain=[NSLayoutConstraint constraintWithItem:mapVC.view attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:10];
    NSLayoutConstraint* leadingConstrain=[NSLayoutConstraint constraintWithItem:mapVC.view attribute:NSLayoutAttributeLeading   relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:10];
    [self.view addConstraints:@[trailConstrain, leadingConstrain]];

}

However, this generates the following runtime exception:

Assertion failure in -[UIView _layoutEngine_didAddLayoutConstraint:
roundingAdjustment:mutuallyExclusiveConstraints:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3600.7.47/NSLayoutConstraint_UIKitAdditions.m:649
    **Impossible to set up layout with view hierarchy unprepared for constraint**

I looked at other threads and the problem was that they had set up constraints in viewDidLoad, but I haven't done that.


Solution

  • (1) Never never never call viewDidLoad. It's not your method to call. Delete that line immediately.

    (2) The problem with your code is that you have no idea when it will be called. Add a check to make sure mapVC.view is in your interface; if not, don't run that code.

    (3). You cannot just take a view controller's view and plunk it into your interface. You have to act as a parent view controller. You're not doing that. That's illegal.