4

iOS9 seems to ignore destination view controller's edgesForExtendedLayout when implementing custom animation using UIViewControllerAnimatedTransitioning, therefore the content ends up below the navigation bar. Any idea why this is happening?

I've hosted an example at https://github.com/nmarkovic04/CustomAnimationTest. Running it on 8.4 and 9.1 shows the difference but you can most likely try any other 8.x and 9.x version.

Running on XCode 7, Swift 2.0.

screenshot

Mercurial
  • 2,095
  • 4
  • 19
  • 33
  • Related question: "[iOS 9: push/pop view controller broken by edgesForExtendedLayout](https://stackoverflow.com/questions/32700122/ios-9-push-pop-view-controller-broken-by-edgesforextendedlayout)". – Gary May 22 '17 at 09:07

4 Answers4

5

this in ViewDidLoad fixes it can you confirm pls :]

self.edgesForExtendedLayout = .Top self.extendedLayoutIncludesOpaqueBars = true

David Yang Liu
  • 1,170
  • 2
  • 10
  • 19
3

You have to setup proper toViewController's frame. transitionContext.finalFrame(for:) will help you. This is my animateTransition(using:) function for fade in/out animation. That one line setting up frame will also fix your shared project.

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

        if let toViewController = transitionContext.viewController(forKey: .to) {

            transitionContext.containerView.addSubview(toViewController.view)
            toViewController.view.frame = transitionContext.finalFrame(for: toViewController)
            toViewController.view.alpha = 0.0

            UIView.animate(withDuration: 0.5,
                           animations: {
                            toViewController.view.alpha = 1.0},
                           completion: { finished in
                            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)})
        }
    }
Viktor Kucera
  • 6,177
  • 4
  • 32
  • 43
  • Thank you, man! Please, take a little improvement for your excellent solution: ``` let toViewFrame = transitionContext.finalFrame(for: toViewController) toView.frame = toViewFrame toView.frame.origin.x = presenting ? toView.frame.width : -toView.frame.width ``` – adnako Sep 05 '19 at 17:14
1

Just setting this:

  self.edgesForExtendedLayout = UIRectEdgeTop;

Resolved the issue for me.

maxshuty
  • 9,708
  • 13
  • 64
  • 77
  • Nah, not really. You can try it in the example I've posted. You actually do want to have .None so the content doesn't go under the nav bar. – Mercurial Oct 19 '15 at 20:33
1

I know this is awful, but in viewDidLoad() i solved with this:

var frame = self.view.frame
frame.origin.y = 64 //The height of status bar + navigation bar
self.view.frame = frame

For me the problem comes out the first time my view controller is seen, when i rotate the device the problem is gone.

  • For me the first time my view is presented it works fine, just when I present the view again it happens. Rotating landscape and back adjust it. – Ace Green May 14 '16 at 01:06
  • When using a `UISplitViewController` in the `collapsed` mode (horizontally Compact) and showing a detail pane, the iOS implementation of `-[showDetailViewController:sender:]` possibly "fakes" `[pushViewController:animated:]` with a custom transition animation, which (incorrectly) ignores `edgesForExtendedLayout`. The only way to QFE this that I found was to `[UIView performWithoutAnimation:^{ /* ... */ }]`. – Gary May 22 '17 at 09:15