Search code examples
iosobjective-cios8uipageviewcontrollerchildviewcontroller

Frame incorrect in parentVC and childVC after popping back to parentVC


I'm having problem were my views frames are completely wrong after return to the viewController by popping the current one.

My view hierarchy is as follows:

UITabbarController,
    UINavigationController
        HomeSwipeViewController (need as I cant put a UIPageViewController straight into a navController)
            UIPageViewController
                 HomeViewController

In the HomeSwipeViewController I have the pageViewController embedded in a containerView, the containerView has constraints and should be full to it's super (set in the storyboard):

self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];

[self.containerView addSubview:self.pageController.view];
[self addChildViewController:self.pageController];
[self.pageController didMoveToParentViewController:self];

[self.pageController.view addFullScreenConstraint]; // full to superView

Inside the homeViewController is a collectionView which you can tap and I push a ViewController on to the UINavigationController. This works fine but when I pop back to the HomeSwipeViewController, the frames are all incorrect.

Logs printed out in viewDidAppear of homeSwipeViewController:

First appears:

[12234:152630] containerView: <UIView: 0x7fea0046cdb0; frame = (0 0; 320 464); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x7fea0046c450>>
[12234:152630] pageController.view: <_UIPageViewControllerContentView: 0x7fea0290b690; frame = (0 0; 320 464); clipsToBounds = YES; opaque = NO; autoresize = W+H; layer = <CALayer: 0x7fea02909f60>>
[12234:152630] self.view: <UIView: 0x7fea0285d2d0; frame = (0 64; 320 504); autoresize = W+H; layer = <CALayer: 0x7fea0285d1d0>>

After pop:

[12234:152630] containerView: <UIView: 0x7fea0046cdb0; frame = (0 0; 0 0); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x7fea0046c450>>
[12234:152630] pageController.view: <_UIPageViewControllerContentView: 0x7fea0290b690; frame = (0 0; 0 0); clipsToBounds = YES; opaque = NO; autoresize = W+H; layer = <CALayer: 0x7fea02909f60>>
[12234:152630] self.view: <UIView: 0x7fea0285d2d0; frame = (0 64; 320 455); autoresize = W+H; layer = <CALayer: 0x7fea0285d1d0>>

I've tried calling setNeedsDisplay, setNeedsLayout and setNeedsUpdateConstraints in the viewDidAppear. Adding constraints all programmatically in viewDidLayoutSubViews.

No broken constraints are logged in the console.

I believe it has to to do with embedding the viewController because when I remove the UIPageViewController and add the homeViewContoller as the childViewController, the same results happen.

If I embed nothing there isn't a problem.

All views have translatesAutoresizingMaskIntoConstraints = NO


Solution

  • I fixed this by setting the constraints for the parent view controller (HomeSwipeViewController) in viewDidLayoutSubviews. I use only do it when self.view.translatesAutoresizingMaskIntoConstraints = YES;

    I think this is because the project uses both views that have been mordenised to Autolayout and frame based(autoresizing) views. It looks like pushing a VC with the view that doesn't have autolayout, removes the VC its coming from constraints or maybe it just inactivates the auto layout engine.

    - (void)viewDidLayoutSubviews {
    
        if (self.view.superview) {
    
            self.view.translatesAutoresizingMaskIntoConstraints = NO;
    
            [self.view.superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[view]|" options:kNilOptions metrics:nil views:@{@"view": self.view}]];
            [self.view.superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-64-[view]|" options:kNilOptions metrics:nil views:@{@"view":self.view}]];
    
        }
    
        [super viewDidLayoutSubviews];
    }  
    

    Any insight to why this works would be cool!