iOS 8 - Screen blank after dismissing view controller with custom presentation

22,221

Solution 1

This is because you are most likely adding both the presenting

[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]

and the presented

[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]

view controllers to your containerView in the (void)animateTransition:(id )transitionContext method of your animation controller. Since you are using a custom modal presentation, the presenting view controller is still shown beneath the presented view controller. Now since it's still visible you don't need to add it to the container view. Instead only add the presented view controller to the containerView. Should look something like this inside of your animateTransition: method

UIView *containerView = [transitionContext containerView];
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

// Boolean value to determine presentation or dismissal animation
if (self.presenting){        
    [transitionContext.containerView addSubview:toViewController.view];
    // Your presenting animation code
} else {
    // Your dismissal animation code
}

Solution 2

This is the kind of question that the high-votes & accepted answer mislead people. Long words short.

Firstly, don't use UIModalPresentationCustom, it's not what it sounds like. (detail)

Secondly, there is a new method to retrieve from/to Views in animateTransition, don't use something like 'fromVC.view' anymore. (why)

UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];

//swift
let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
let toView = transitionContext.viewForKey(UITransitionContextToViewKey)

Now the black screen should go away.

Solution 3

It seems I encountered the same issue, I'm using Xcode 6 beta5.

I searched with Google and found someone else has this same issue, and they said this is serious a bug in iOS 8, so hope Apple can fix this soon.

https://github.com/TeehanLax/UIViewController-Transitions-Example/issues/5

Solution 4

Perhaps the view hierarchy is buggy with new Xcode or maybe it's a little different is iOS8. This code worked for me. Add it while dismissing the controller in animateTransition: transitionContext method.

[[UIApplication sharedApplication].keyWindow addSubview:toViewController.view];
toViewController.view.userInteractionEnabled = YES;

Solution 5

I added the code below to the transition completion block and it fixed it for me.

[UIView animateWithDuration:[self transitionDuration:transitionContext] animations: ^{
    // Animation code

 } completion: ^(BOOL finished) {
     // More of your code

     // Add the following line before completing the transition
    [[[UIApplication sharedApplication] keyWindow] sendSubviewToBack:toViewController.view];

    // Complete the transition
    [transitionContext completeTransition:YES];
}];
Share:
22,221
jaggedcow
Author by

jaggedcow

I'm not interesting.

Updated on July 05, 2022

Comments

  • jaggedcow
    jaggedcow almost 2 years

    When dismissing various view controllers using UIModalPresentationCustom, the screen turns black after the view controller is dismissed, as if all the view controllers had been removed from the view hierarchy.

    The transitioning delegate is set properly, the animationControllerForPresentedController is asked for and passed correctly, and the transition is completed once the animation is over.

    This exact code works perfectly when compiled with the iOS 7 SDK, but is broken when compiled with iOS 8b5

  • Stas Zhukovskiy
    Stas Zhukovskiy over 9 years
    This is the correct answer and should be accepted. There was a bug in iOS 7, which they fixed in iOS 8. The solution above works perfectly on iOS 7 and 8. Thanks DJSK for pointing this out, spent some time figuring out how do I get a blank screen.
  • Stas Zhukovskiy
    Stas Zhukovskiy over 9 years
    This is not a bug in Xcode or iOS 8. The correct solution is provided by DJSK.
  • Mike Pollard
    Mike Pollard over 9 years
    I concur with @StasZhukovskiy. This solves the issue. One remaining problem I find is that the presented/dismissed ViewController leaks in iOS7.0, although not 7.1 or 8...
  • DanZimm
    DanZimm over 9 years
    Apparently this is not the correct answer - according to the UIViewControllerContextTransitioning header we should use -viewForKey method to get the views. Unfortunately with the presentation style of UIModalPresentationCustom causes -viewForkey to return nil in some cases which is apparently the desired behavior.... Check out bcherry's answer over here.
  • Matrosov Oleksandr
    Matrosov Oleksandr over 9 years
    I don't know but by some reason I don't see view of controller that presented my view controller after dimiss
  • denvdancsk
    denvdancsk over 9 years
    @DanZimm using [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKe‌​y].view or [transitionContext viewForKey:UITransitionContextFromView] doesn't matter. They are the exact same thing. The issue when using a custom modal transition, is that (in iOS8) if you add the fromView to the animation controller, it's not returned to the original hierarchy when the animation completes. You can either manually return it afterwards or you can choose to not add it at all.
  • DanZimm
    DanZimm over 9 years
    @DJSK I was quoting Apple's docs. The header specifically says not to use the viewControllerForKey:UITransitionContextFromViewControllerKe‌​y to get the view.
  • denvdancsk
    denvdancsk over 9 years
    Isn't that only if your building for iOS8 only and won't work if you want to target iOS7 and iOS8 together?
  • Colas
    Colas about 9 years
    @DJSK Does your post answer my other question there? Thanks
  • denvdancsk
    denvdancsk about 9 years
    Yes, this solutions applies and in my opinion is the easiest. However, DanZimm's solution works as well but you would need to add an if statement in your animation controller object class to determine what version of iOS the app is running on. Then add the views to the animation controller object using the View Controller Transition Keys for iOS7 and the View Transition Keys for iOS8.
  • Lcsky
    Lcsky over 8 years
    It may not a bug in iOS but in our own code. Did you set modalPresentationStyle to UIModalPresentationCustom, but not implemented the presentationControllerForPresentedViewController method? See here: stackoverflow.com/a/25655575/466965
  • denvdancsk
    denvdancsk over 8 years
    This is definitely the correct way to achieve this if you're developing for specific versions of iOS like 8 or greater. The answer I provided is just an easy way to achieve the same thing without having to check or be specific, while also accommodating iOS7.
  • lostAtSeaJoshua
    lostAtSeaJoshua about 8 years
    This is the exact fix for the problem I was having. The problem I was facing was calling dismiss view controller with or without custom animation after presenting from a custom animation would cause the screen to just go back. Removing adding both the presented and presenting fixed the issue. It even caused multiple views to constantly stack with out dismissing. This fix was great. Thank you!
  • Anita Nagori
    Anita Nagori about 7 years
    how to get transitionContext ?
  • Tepmnthar
    Tepmnthar about 3 years
    This answer is correct. Solve problems on ios12. Thought this is a system bug.