Navigation controller top layout guide not honored with custom transition

前端 未结 12 1510
暖寄归人
暖寄归人 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:38

    I ran into this same issue but without using a UINavigationController and just positioning a view off of the topLayoutGuide. The layout would be correct when first displayed, a transition would take place to another view, and then upon exiting and returning to the first view, the layout would be broken as that topLayoutGuide would no longer be there.

    I solved this problem by capturing the safe area insets prior to the transition and then reimplementing them, not by adjusting my constraints, but by setting them on the viewController's additionalSafeAreaInsets.

    I found this solution to work well as I don't have to adjust any of my layout code and search through constraints and I can just reimplementing the space that was there previously. This could be more difficult if you are actually using the additionalSafeAreaInsets property.

    Example

    I added a variable to my transitionManager to capture the safe insets that exist when the transitionManager is created.

    class MyTransitionManager: NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate {
    
        private var presenting = true
        private var container:UIView?
        private var safeInsets:UIEdgeInsets?
    
        ...
    

    Then during the entering transition I save those insets.

        let toView = viewControllers.to.view
        let fromView = viewControllers.from.view
    
        if #available(iOS 11.0, *) {
            safeInsets = toView.safeAreaInsets
        }
    

    In the case of the iPhone X this looks something like UIEdgeInsets(top: 44.0, left: 0.0, bottom: 34.0, right: 0.0)

    Now when exiting, the insets on that same view we transitioned from in the entrance will be .zero so we add our captured insets to the additionalSafeAreaInsets on the viewController, which will set them on our view for us as well as update the layout. Once our animation is done, we reset the additionalSafeAreaInsets back to .zero.

        if #available(iOS 11.0, *) {
            if safeInsets != nil {
                viewControllers.to.additionalSafeAreaInsets = safeInsets!
            }
        }
    
        ...then in the animation completion block
    
        if #available(iOS 11.0, *) {
            if self.safeInsets != nil {
                viewControllers.to.additionalSafeAreaInsets = .zero
            }
        }
    
        transitionContext.completeTransition(true)
    

提交回复
热议问题