I am trying present a navigation controller with UITabBarController, I am confused why UITabBarController's viewDidAppear is not called again after the navigation controller dismissed. How can I manage to do that?
Change presentation style to currentContext. For example:
let controller = ViewController()
controller.modalPresentationStyle = .currentContext //<-- Add this line
self.present(controller, animated: true, completion: nil)
Related
If I present a ViewController like so:
let authViewController = authUI!.authViewController()
authViewController.modalPresentationStyle = .overCurrentContext
self.present(authViewController, animated: true, completion: nil)
I would like to know when the ViewController has been dismissed. I have tried the following:
let authViewController = authUI!.authViewController()
authViewController.modalPresentationStyle = .overCurrentContext
self.present(authViewController, animated: true, completion: {
print("View Dismissed")
})
but that only lets me know if the view was presented successfully. This ViewController was not created by me so I can't change the viewWillDissapear method.
Whole answer is predicated on an assumption that OP doesnt have access to authViewController code
If you dont have access to authViewController code, lousy solution would be to use viewWillAppear of your view controller to find when auth view controller is dismissed.
Basically when you present/push any viewController over your existing view controller, your view controller's viewWillDisappear will be called similarly when presented/pushed view controller is dismissed, or popped out viewWillAppear will be called.
Because viewWillAppear might get called for other reasons as well and you wouldnt wanna confuse it as authViewController dismiss, use a boolean
private var shouldMonitorAuthViewControllerDismiss = false //declared a instance property
Set the boolean to true when you actually present the authViewController
let authViewController = authUI!.authViewController()
authViewController.modalPresentationStyle = .overCurrentContext
self.present(authViewController, animated: true, completion: {
shouldMonitorAuthViewControllerDismiss = true
})
Finally in your viewWillAppear
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
if shouldMonitorAuthViewControllerDismiss {
//auth view controller is dismissed
}
shouldMonitorAuthViewControllerDismiss = false
}
I have a weird behavior when presenting UIViewControllers modally in iOS 13. The new presentation style that I've seen all across iOS 13 looks like this:
The presenting view controller appears behind the presented view controller. It is also shifted down to mimic a "stack"
Meanwhile, when presenting view controllers through my app, I keep getting this effect:
The presenting view controller doesn't move at all when presenting a new view controller
I use this code to present this view controller:
let controller = storyboard?.instantiateViewController(withIdentifier: "tutorial") as! TutorialController
controller.modalPresentationStyle = .pageSheet
controller.modalTransitionStyle = .coverVertical
present(controller, animated: true, completion: nil)
Here is my question:
I'm wondering why this is happening and if there is a way to present view controllers in the normal iOS 13 style (with the presenting view controller moving back).
Thanks in advance!
Turns out the problem was my view controller hierarchy. I was able to fix it by making the presenting view controller the root view controller of my app. First I set the background controller as the root view controller by calling
window.rootViewController = self
and then using my previous code
let controller = storyboard?.instantiateViewController(withIdentifier: "tutorial") as! TutorialController
controller.modalPresentationStyle = .pageSheet
controller.modalTransitionStyle = .coverVertical
present(controller, animated: true, completion: nil)
I presented the view controller. Thanks to everyone who tried to help!
I think the issue can be resolved by using vc.modalPresentationStyle = .fullScreen if there is not UINavigationController , otherwise you can use these codes as follows:
let navigationController = UINavigationController(rootViewController: vc)
navigationController.modalPresentationStyle = .fullScreen
present(vc, animated: true)
because With iOS 13 this is a new feature that Apple has changed the default presentation style of View Controllers to a modal sheet from fullscreen in iOS 12
Programmatically:
let vc = UIViewController()
vc.modalPresentationStyle = .fullScreen //or .overFullScreen for transparency
self.present(vc, animated: true, completion: nil)
From storyboard:
That's it. No need to play with root controller or window at all.
For reference, visit this article.
iOS13: Let's say you have 3 view controllers: FirstVC, SecondVC, ThirdVC
FirstVC presents SecondVC with the below code:
let secondVC = SecondVC()
secondVC.modalPresentationStyle = .fullScreen
firstVC.present(secondVC, animated: true, completion: nil)
SecondVC presents ThirdVC with the below code:
let thirdVC = ThirdVC()
secondVC.present(thirdVC, animated: true, completion: nil)
Changing secondVC's modalPresentationStyle to .currentContext solves the problem.
We can change it in the Inspector Tool Bar. To Achieve it: head over to the fifth section of Inspector Tollbar then change the Presentation field to Full Screen.
This should be the only property you need to set
presentedViewController.modalPresentationStyle = .automatic
Detailed in
https://developer.apple.com/videos/play/wwdc2019/224/
I want to be able to present a viewController with crossDissolve but dismiss it with the traditional top to bottom dismissal.
Is there a way to change the modalTransitionStyle once the viewController has opened?
Here is how I am currently presenting
I want to be able to present a viewController with crossDissolve but dismiss it with the traditional top to bottom dismissal.
Is there a way to change the modalTransitionStyle once the viewController has opened?
Here is how I am currently presenting
let layout = UICollectionViewFlowLayout()
let userSearchController = UserSearchController(collectionViewLayout: layout)
userSearchController.modalTransitionStyle = .crossDissolve
currentController?.present(userSearchController, animated: true, completion: nil)
Using #Jason's comment I did the following
userSearchController.modalTransitionStyle = .crossDissolve
currentController?.present(userSearchController, animated: true, completion: {
userSearchController.modalTransitionStyle = .coverVertical
})
and it works perfectly
I have a UINavigation controller. The viewController contents is as follows
[RestaurantViewController, MenuViewController, ProductViewController]
In ProductViewController I call
self.navigationController?.present(sideViewController, animated:true, completion:nil)
This presents the view controller as expected. Now when I call self.dismiss/self.presentingViewController.dismiss from within sideViewController, the original NavigationController Resets to
[RestaurantViewController]
Why is this? I just want to dismiss and be returned to the presenting viewController
Why not just present the controller from ProductViewController using
self.present(sideViewController, animated:true, completion:nil)
Then dismiss using
self.dismiss(animated: true , completion: nil)
Other than that there could be many things that could cause your issues. If you want a navigation controller on the sideViewController then create a navigation controller and set sideViewController as the rootviewcontroller and present the navigation controller.
let nav = UINavigationController(rootViewController: //SideViewController)
self.present(nav, animated: true, completion: nil)
I'm trying to make ViewController present after Modal dismiss
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let chatRoomVC = storyboard.instantiateViewController(withIdentifier: "ChatRoomVCId") as! ChatRoomVC
chatRoomVC.hidesBottomBarWhenPushed = true
chatRoomVC.passValue = passValue
self.dismiss(animated: true, completion: {
self.present(chatRoomVC, animated: true, completion: nil)
})
But it will return "whose view is not in the window hierarchy!" maybe it's present a view after the controller dismissed
Notice the self in self.present, what you are doing, is basically tell the vc that you are dismissing to present a new vc, thats wrong way to do, the correct way is tell it's PARENT vc to present a new vc, by using delegate/unwind to call the parent vc to present new vc
You are using self. It means you are dismissing the current view controller. It should be the parent view controller who will present a new view controller.
When present from "Controller_A" to "Controller_B"-> present it like given below
--- View Controller A ---
self.navigationController?.present(Controller_B, animated: true, completion: nil)
When you want to dismiss "Controller_B" and present "Controller_C" using Navigation controller
--- View Controller B ---
let presenController : UINavigationController = self.presentingViewController as! UINavigationController
presentingController.dismiss(animated: true, completion: {
presenController.pushViewController(Controller_C, animated: true)
})