iOS 8 - Screen blank after dismissing view controller with custom presentation
IosObjective CCocoa TouchUikitIos8Ios Problem Overview
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
Ios Solutions
Solution 1 - Ios
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
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 - Ios
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 - Ios
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 - Ios
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];
}];
Solution 5 - Ios
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 6 - Ios
Quick Tip: Make sure your "From" UIViewController is what you're expecting.
NSLog(@" FROM vc %@" , [[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey] description]);
Had a similar bug in my code in the past. You can easily pull out the right "From" VC context.
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
fromView = [[[fromVC childViewControllers] firstObject] view];
Solution 7 - Ios
I had the same problem, and what caused the problem for me is that I wasn't setting the toViewController's final frame. See the following example from http://www.appcoda.com/custom-view-controller-transitions-tutorial/
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
let finalFrameForVC = transitionContext.finalFrameForViewController(toViewController)
let containerView = transitionContext.containerView()
let bounds = UIScreen.mainScreen().bounds
toViewController.view.frame = CGRectOffset(finalFrameForVC, 0, bounds.size.height)
containerView.addSubview(toViewController.view)
UIView.animateWithDuration(transitionDuration(transitionContext), delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.0, options: .CurveLinear, animations: {
fromViewController.view.alpha = 0.5
toViewController.view.frame = finalFrameForVC
}, completion: {
finished in
transitionContext.completeTransition(true)
fromViewController.view.alpha = 1.0
})
}