Reputation: 1451
I have two view controllers. On the first one I have a button, which shows the second one modally. Then, I close the second one by tapping a button on it (it goes down). For dismissing transition I have created a custom class which conforms to UIViewControllerAnimatedTransitioning
, so I use a custom transition animation for view controllers (I needed a custom behaviour during the dismissing transition).
My question is the following: because of a custom transition that I use, is my view controller still get removed after the transition finishes or is it still there but off the screen? And if it is, will it affect the memory and how bad?
Upvotes: 3
Views: 2756
Reputation: 12214
The ViewController
remains in the hierarchy.
You can confirm this by verifying the value of self.parentViewController
property in the modal view controller.
Edit:
Will that view controller affect the memory?
Yes it will continue to perform all operations or activities (e.g: streaming audio, playing animation, running timers etc) in the parentViewController.
And if so, how can this situation be handled?
There are methods available in UIViewController class to detect when a ViewController will or is appeared / disappeared.
More specifically, following methods are at your disposal:
You can use viewWillAppear
and viewDidAppear
in parentViewController
to start or resume such activities / operations.
And viewWillDisappear
and viewDidDisappear
to suspend or stop such activities / operations.
Hope this helps.
Upvotes: 2
Reputation: 438287
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 }
}
Upvotes: 6
Reputation: 19767
I'm going assume that you are speaking about the view
of your modal viewController
staying in the window hierarchy - since you are asking if it is still there but off the screen, I believe you are talking about the view, and the controller, since controller is never on the screen.
And if you are asking about the view
(which I assume that you are), calling completeTransition
on transitionContext
will remove it from the window hierarchy (so there is no need to call fromVC.view.removeFromSuperview()
) - and by contract you are required to call completeTransition
when the transition finishes in the UIViewControllerAnimatedTransitioning
implementation.
You can confirm this behavior by checking the value of fromVC.view.superview
before and after calling transitionContext.completeTransition
:
UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
fromVC.view.frame = endFrame
}) { (_) in
print(">>> \(fromVC.view.superview)")
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
print(">>> \(fromVC.view.superview)")
}
Upvotes: 1
Reputation: 14123
Yes, the previous UIViewController remains there.
As described in Apple docs
viewControllerToPresent
The view controller to display over the current view controller’s content.
Upvotes: 0