iOS 8 - Screen Blank After Dismissing View Controller with Custom Presentation

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

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
}

Dismissing modal view controller results in a black screen

I found the solution - this answer really helped. The trick was in dismissing the view controller. It should be done like this:

[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];

and not like this:

[self dismissViewControllerAnimated:YES completion:nil];

Although the author of the linked answer suggests that a better approach would be to use delegation (presentED VC would define a protocol and presentING VC would subscribe to it and then dismiss the presentED VC once it asks for it), it wasn't feasible in my case.

Black screen when dismissing a UIViewController with custom transition from within a UINavigationController

I figured it out. The problem was when I was adding the view to the transition context container view:

 [self.containerView insertSubview:self.fromViewController.view belowSubview:self.toViewController.view];

In stead I needed to add the view from the navigation controller:

[self.containerView insertSubview:navigationController.view belowSubview:self.toViewController.view];

Black screen after presenting modal view controller in current context from UITabBarController

I had the same issue and was able to solve it by setting self.definesPresentationContext = YES; on the presenting view controller before presenting the modal VC. You can also set this in a storyboard, the checkbox is called "Defines Context" in Interface Builder.

Does a view controller get removed entirely when using a custom transition?

You said:

is my view controller still get removed after the transition finishes or is it still there but off the screen?

There are two completely separate issues here.

First, there is a question of the view controller hierarchy. When you present a new view controller, the old view controller is always kept in the view controller hierarchy so that when you dismiss back to it, it will still be there. However, when you dismiss, the dismissed view controller will be removed from the view controller hierarchy and (unless you do something unusual, like keeping your own strong reference to it somewhere) it will be deallocated.

Second, there is a separate question of the view hierarchy. When presenting, the UIPresentationController dictates whether the presenting view controller's view remains in the view hierarchy or not. By default, it keeps it in the view hierarchy, but generally if doing a modal, full-screen "present", you'd specify a UIPresentationController subclass that tells it to remove the presenting view controller's view when the transition is done.


For example, when doing a custom modal "present" transition where the presented view controller's view is opaque and covers the whole screen, then your UIViewControllerTransitioningDelegate would not only supply the animation controllers, but also specify a presentation controller:

func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return YourAnimationController(...)
}

func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return YourAnimationController(...)
}

func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
return PresentationController(presentedViewController: presented, presenting: presenting)
}

And that presentation controller might be fairly minimal, only telling it to remove the presenter's view:

class PresentationController: UIPresentationController {
override var shouldRemovePresentersView: Bool { return true }
}

Detecting sheet was dismissed on iOS 13

Is there a way to detect that the presented view controller sheet was dismissed?

Yes.

Some other function I can override in the parent view controller rather than using some sort of delegate?

No. "Some sort of delegate" is how you do it. Make yourself the presentation controller's delegate and override presentationControllerDidDismiss(_:).

https://developer.apple.com/documentation/uikit/uiadaptivepresentationcontrollerdelegate/3229889-presentationcontrollerdiddismiss


The lack of a general runtime-generated event informing you that a presented view controller, whether fullscreen or not, has been dismissed, is indeed troublesome; but it's not a new issue, because there have always been non-fullscreen presented view controllers. It's just that now (in iOS 13) there are more of them! I devote a separate question-and-answer to this topic elsewhere: Unified UIViewController "became frontmost" detection?.

Trying to dismiss the presentation controller while transitioning already

My solution:

dismissViewControllerAnimated:completion:If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack.

For example,I have 4 views:A->B->C->D and when I want to dismiss B, I firstly check if C also want to dismiss by using objc_setAssociatedObject to attach/detach a NSString object, and if C wants to dismiss too,then just cancel C's request.Just call dismiss to B.



Related Topics



Leave a reply



Submit