Navigation controller top layout guide not honored with custom transition

前端 未结 12 1523
暖寄归人
暖寄归人 2020-12-04 11:35

Short version:

I am having a problem with auto layout top layout guide when used in conjunction with custom transition and UINavigationController in iO

12条回答
  •  臣服心动
    2020-12-04 11:47

    Here's the simple solution I'm using that's working great for me: during the setup phase of - (void)animateTransition:(id)transitionContext, manually set your "from" and "to" viewController.view.frame.origin.y = navigationController.navigationBar.frame.size.height. It'll make your auto layout views position themselves vertically as you expect.

    Minus the pseudo-code (e.g. you probably have your own way of determining if a device is running iOS7), this is what my method looks like:

    - (void)animateTransition:(id)transitionContext
    {
        UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
        UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
        UIView *container = [transitionContext containerView];
    
        CGAffineTransform destinationTransform;
        UIViewController *targetVC;
        CGFloat adjustmentForIOS7AutoLayoutBug = 0.0f;
    
        // We're doing a view controller POP
        if(self.isViewControllerPop)
        {
            targetVC = fromViewController;
    
            [container insertSubview:toViewController.view belowSubview:fromViewController.view];
    
            // Only need this auto layout hack in iOS7; it's fixed in iOS8
            if(_device_is_running_iOS7_)
            {
                adjustmentForIOS7AutoLayoutBug = toViewController.navigationController.navigationBar.frame.size.height;
                [toViewController.view setFrameOriginY:adjustmentForIOS7AutoLayoutBug];
            }
    
            destinationTransform = CGAffineTransformMakeTranslation(fromViewController.view.bounds.size.width,adjustmentForIOS7AutoLayoutBug);
        }
        // We're doing a view controller PUSH
        else
        {
            targetVC = toViewController;
    
            [container addSubview:toViewController.view];
    
            // Only need this auto layout hack in iOS7; it's fixed in iOS8
            if(_device_is_running_iOS7_)
            {
                adjustmentForIOS7AutoLayoutBug = toViewController.navigationController.navigationBar.frame.size.height;
            }
    
            toViewController.view.transform = CGAffineTransformMakeTranslation(toViewController.view.bounds.size.width,adjustmentForIOS7AutoLayoutBug);
            destinationTransform = CGAffineTransformMakeTranslation(0.0f,adjustmentForIOS7AutoLayoutBug);
        }
    
        [UIView animateWithDuration:_animation_duration_
                              delay:_animation_delay_if_you_need_one_
                            options:([transitionContext isInteractive] ? UIViewAnimationOptionCurveLinear : UIViewAnimationOptionCurveEaseOut)
                         animations:^(void)
         {
             targetVC.view.transform = destinationTransform;
         }
                         completion:^(BOOL finished)
         {
             [transitionContext completeTransition:([transitionContext transitionWasCancelled] ? NO : YES)];
         }];
    }
    

    A couple of bonus things about this example:

    • For view controller pushes, this custom transition slides the pushed toViewController.view on top of the unmoving fromViewController.view. For pops, fromViewController.view slides off to the right and reveals an unmoving toViewController.view under it. All in all, it's just a subtle twist on the stock iOS7+ view controller transition.
    • The [UIView animateWithDuration:...] completion block shows the correct way to handle completed & cancelled custom transitions. This tiny tidbit was a classic head-slap moment; hope it helps somebody else out there.

    Lastly, I'd like to point out that as far as I can tell, this is an iOS7-only issue that has been fixed in iOS8: my custom view controller transition that is broken in iOS7 works just fine in iOS8 without modification. That being said, you should verify that this is what you're seeing too, and if so, only run the fix on devices running iOS7.x. As you can see in the code example above, the y-adjustment value is 0.0f unless the device is running iOS7.x.

提交回复
热议问题