Here i'm dismissing one VC and trying to navigate new VC , but navigation not working. Dismiss VC working fine.
#IBAction func onClickEmailBtn(_ sender: UIButton) {
//dismiss VC
self.dismiss(animated: false, completion: nil)
//Navigate to VC
DispatchQueue.main.async {
let cevc = self.storyboard?.instantiateViewController(withIdentifier: "CEVC") as! EmailViewController
self.navigationController?.pushViewController(cevc, animated: true)
}
}
Here I have one NavigationViewController called VC1, on that I'm presenting one VC called VC2. In this VC2 when I click button I want to navigate new VC called EmailVC.
try this code
#IBAction func onClickEmailBtn(_ sender: UIButton) {
if let controller = self.storyboard?.instantiateViewController(withIdentifier: "CEVC") as! EmailViewController {
self.dismiss(animated: false, completion: nil)
self.presentingViewController?.present(controller, animated: true, completion: nil)
}
}
You were trying to push a ViewVontroller from dismissing view controller,
and the answer which you have accepted is presenting a viewController from dismissing viewController. Although it may serve your purpose, but I am going to answer you original question
// get the object of presenting nanvigation controller(navigation controller with has presented this view controller)
let presentingNavigationController = presentingViewController?.navigationController
dismiss(animated: true) {
let cevc = self.storyboard?.instantiateViewController(withIdentifier: "CEVC") as! EmailViewController
// here you push your view controller with presentingNavigationController
presentingNavigationController?.pushViewController(cevc, animated: true)
}
Try to find out Navigation controller using below code and replace Viewcontroller with your Controller name.
let productVC = SeconViewViewController()
let parentVC = (parent!.presentingViewController as! ViewController).childViewControllers.first as! UINavigationController
self.navigationController?.dismiss(animated: true, completion: {
parentVC.pushViewController(productVC, animated: true)
})
Related
I have two navigation controllers as follows:
Navigation controller1 -> View controller1
Tab view Controller -> Navigation controller2 -> View controller2
When I'm in View controller2 and pressed back button, I want to go to View controller1. It is working fine with built in back button in navigation bar, but when I tried to write my own it doesn't work.
I have tried the following statements but they didn't work:
self.dismiss(animated: true, completion: nil)
self.navigationController?.dismiss(animated: true, completion: nil)
navigationController?.popViewController(animated: true)
let story = UIStoryboard(name: "Main", bundle: nil)
let pushVC = story.instantiateViewControllerWithIdentifier("VC1")
let navigation = story.instantiateViewControllerWithIdentifier("Navigation1") as! UINavigationController
navigation.pushViewController(VC1!, animated: true)
if you are using navigationController in the first one only then you can use this to navigate to your ViewController2:
let vc2 = storyboard?.instantiateViewController(identifier: "ViewController2") as! ViewController2
navigationController?.showDetailViewController(vc2, sender: self)
Then if you wanna back from viewController2 to ViewController1 you can create cancel button and connect its action and write this in the action:
#IBAction func buttonCancelAction(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
But if there is a navigationController in both ViewController1 & ViewController2 then you will use the below:
let VC2 = storyboard?.instantiateViewController(identifier: "ViewController2") as! ViewController2
navigationController?.pushViewController(VC2, animated: true)
and you can pop it (Dismiss it):
#IBAction func buttonCancelAction(_ sender: Any) {
navigationController?.popViewController(animated: true)
}
I have a Feedback View Controller that is accessed in 7 locations across 4 different screens.
One way it's presented in a navigationController via pushViewController. The other 6 times it's presented modally.
Here's the function that opens the Feedback VC's
struct Constants{
static func openFeedback(openFrom: UIViewController, nav:Bool) {
let fbStoryboard = UIStoryboard(name: "FeedbackViewController", bundle: nil)
let fbVC = fbStoryboard.instantiateViewController(withIdentifier: "FBSBID")
fbVC.modalPresentationStyle = .overFullScreen
fbVC.modalTransitionStyle = .crossDissolve
if nav {
openFrom.navigationController?.pushViewController(fbVC, animated: true)
} else {
openFrom.present(fbVC, animated: true, completion: nil)
}
}
}
The Feedback VC is called with either Constants.openFeedback(openFrom: self, nav: true) or Constants.openFeedback(openFrom: self, nav: false)
Opening the VC works just fine!
Here's my close button on the Feedback View Controller:
#IBAction func closeButtonPressed(_ sender: UIButton) {
self.dismiss(animated: true, completion: nil)
}
Which works 6 out of the 7 times, when not in the navigation stack. When it's in the navigation stack, the close button does not do anything.
My question is, how do I close out of the Feedback View Controller, based on if it's in the navigationController stack or not?
You can simply check if view controller is embedded inside UINavigationController by checking if controller's navigationController is nil or not.
So if it is embedded you can use popViewController(animated:) on navigation controller to "dismiss" pushed controller
if let navCon = navigationController {
navCon.popViewController(animated: true)
} else {
dismiss(animated: true)
}
I'm trying to present a view controller and dismiss my current modal view. I saw the answers on StackOverflow, but I don't understand it.
self.dismissViewControllerAnimated(true, completion: {
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("myViewController")
self.presentViewController(vc!, animated: true, completion: nil)
})
Could anyone please tell me, how to do it simply? Thanks
Check your main controller in stack and pop all other view controllers and then present new View Controller.
if let controllers = self.navigationController?.viewControllers {
for vc in controllers {
// Check if the view controller is of MainViewController type
if let myVC = vc as? MainViewController {
self.navigationController?.popToViewController(myVC, animated: false)
}
}
}
Push view controller :
let secondVC = self.storyboard?.instantiateViewController(withIdentifier: "secondVC") as! SecondViewController
self.navigationController?.pushViewController(secondVC, animated: true)
or Present View Controller :
let next = self.storyboard?.instantiateViewController(withIdentifier: "secondVC") as! SecondViewController
self.present(next as UIViewController, animated: true, completion: nil)
You can use this code to Present viewcontroller.
let yourVC = UIStoryboard(name: storyBord, bundle: nil).instantiateViewController(withIdentifier:ID) as! yourViewController
let navController = UINavigationController(rootViewController: yourVC)
self.present(navController, animated: true, completion: {
})
And for dissmissing use this in your presented viewController
self.dismiss(animated: true, completion: {
})
I have a question regarding blureffects on a view controller. I program all of my segues manually for several reasons. But when I go to a viewcontroller that has a blureffect background, I only see a dark gray background. How can I solve this that the view controller blur effect lays on top of another viewcontroller where the content of the previous viewcontroller can be seen through?
The blureffects are now applied by storyboard with transparant background views.
My code for seque is:
Action:
#IBAction func ToUserSections(_ sender: Any) {
let controller =
Navigation.getDestinationViewControllerWith("User",
controllerName: "UserSectionsVC")
present(controller, animated: false, completion: nil)
}
Class:
class Navigation{
static func getDestinationViewControllerWith(_
storyboardName:String, controllerName:String)-> UIViewController{
let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
let controller =
storyboard.instantiateViewController(withIdentifier:
controllerName) as UIViewController
return controller
}
}
Hope you can help me with this because it will maximize aesthetics for the app :D
try this.
let viewController : CustomViewControlller = UIStoryboard.getMainStoryboard().instantiateViewController(withIdentifier: "Identifier") as! CustomViewControlller
viewController.modalPresentationStyle = .overCurrentContext
viewController.modalTransitionStyle = .crossDissolve
self.present(viewController, animated: true, completion: { _ in })
Alright for others to know, what worked for me was the following:
At IBAction: adding the following line before presenting
controller.modalPresentationStyle = UIModalPresentationStyle.overFullScreen
Like this:
#IBAction func ToUserSections(_ sender: Any) {
let controller = Navigation.getDestinationViewControllerWith("User", controllerName: "UserSectionsVC")
controller.modalPresentationStyle = UIModalPresentationStyle.overFullScreen
present(controller, animated: false, completion: nil)
}
I have a game menu with button start game:
#IBAction func startGame(_ sender: AnyObject) {
if let vc = self.storyboard?.instantiateViewController(withIdentifier: "gameViewController") as? GameViewController {
vc.modalTransitionStyle = .crossDissolve
self.present(vc, animated: true, completion: nil)
}
}
Game over code:
if lifes == 0 {
if let vc = self.storyboard?.instantiateViewController(withIdentifier: "mainMenuViewController") as? MainMenuViewController {
vc.modalTransitionStyle = .crossDissolve
self.present(vc, animated: true, completion: nil)
}
}
When user click on button i show new view controller with Sprite Kit scene. But when game is over i go back to menu. And if we click Start game again, fps falls from 60(in my case) to 30, then if again to 20 etc. Seems like old view controller still working. How to dismiss it ?
I read similar questions, but didn't find answer in them.
Ok, now your issue is clear.
You should not present a new MainViewController when game is over. This will lead you to potentially infinite stack of view controllers like this:
Main -> Game -> Main -> Game -> ...
Instead you should dismiss your Game vc and return to the previous controller, so that you will always have one or two controllers in memory.
So you should replace this:
if lifes == 0 {
if let vc = self.storyboard?.instantiateViewController(withIdentifier: "mainMenuViewController") as? MainMenuViewController {
vc.modalTransitionStyle = .crossDissolve
self.present(vc, animated: true, completion: nil)
}
}
With this:
if lifes == 0 {
dismiss(animated: true, completion: nil) //will bring you to previous Main vc
}
Edit:
If you have more than two controllers to show, you should consider navigation controller approach. Basically you create it with rootViewController (MainVC), then push GameVC, then push GameOver.
In MainVC:
self.navigationController?.pushViewController(gameVC, animated: true)
In GameVC:
self.navigationController?.pushViewController(gameOverVC, animated: true)
To pop only only one controller:
self.navigationController?.popViewController(animated: true)
To pop to the first controller:
self.navigationController?.popToRootViewController(animated: true)