Swift: how to switch back to previous UITableViewController without adding a segue - ios

In my iOS app I would like that, after a positive result, the screen to switch back to the previous screen. In my case I would switch back from a UITableViewController to another UITableViewController. I have tried with:
self.dismissViewControllerAnimated(true, completion:nil)
but it doesn't work, nothing appears.
I have also tried with:
let mainStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let vc : UITableViewController = mainStoryboard.instantiateViewControllerWithIdentifier("Tasks") as UITableViewController
self.presentViewController(vc, animated: true, completion: nil)
but I get "fatal error: unexpectedly found nil while unwrapping an Optional value" in the method viewWillAppear() in:
self.navigationController!.editButtonItem().title = "Modifica"
I with I could avoid add another reverse segue from the interface builder and then perform performSegueWithIdentifier(). Isn't there a faster way?

Are you using a UINavigationController? If so, you just call navigationController?.popViewControllerAnimated(true) to go to the previous screen.
If you aren't using a UINavigationController, you can call dismissViewControllerAnimated(true, completion: nil) to achieve the same result.
In both cases, you don't need to use self as it is already implied.

Related

UINavigationController is nil in swift 3

In my main storyboard I have 1 Navigation controller and subsequent swift file NavigationCtr.swift.
The viewController is in different xib.
Now I want to push my viewController from the NavigationCtr class.
let vcFirst = FirstViewController(nibName: "FirstViewController", bundle: nil)
self.navigationController!.pushViewController(vcFirst, animated: true)
I am getting a exception
fatal error: unexpectedly found nil while unwrapping an Optional value
So when I trying to print from viewDidLoad
print(self.navigationController)
in NavigationCtr.swift class it is giving nil. So nothing works
I created a new project in objective C and it works fine.
Attached the storyboard image
Any hint in the direct direction is highly appreciated.
Note : - I am new to swift
the main issue was using the self.navigationController
As my storyboard only had navigationController I should just self keyword.
as below
let vcFirst = FirstViewController(nibName: "FirstViewController", bundle: nil)
self.pushViewController(vcFirst, animated: true)
For the first controller, set it as rootController instead of push (show).
self.navigationController = UINavigationController(rootViewController: vcFirst)
Or set its view controllers
self.navigationController = UINavigationController()
navigationController.setViewControllers([vcfirst], animated: true)

Dismissing a UINavigationController and Presenting another UINavigationController

I have a two view controllers, ViewControllerA and ViewControllerB, embedded in a UINavigationController. ViewControllerA has a UICollectionView that displays images.
When the camera icon located at index 0 and the UICollectionViewCell is selected, it should dismiss ViewControllerA and display ViewControllerB. And also, there is a ViewController that presents ViewControllerA modally
This is what I've done, but it only dismiss ViewControllerA and nothing happens
let controller = self.storyboard?.instantiateViewControllerWithIdentifier("cameraViewController") as! UINavigationController
self.dismissViewControllerAnimated(true, completion: { () -> Void in
self.presentingViewController?.presentViewController(controller, animated: true, completion: nil)
})
When view controller is dismissed, my guess is self is already deallocated so self.presentingViewController? becomes nil too. I would create a strong reference to presenting view controller right before dismissing action takes place:
let presentingViewController = self.presentingViewController
self.dismissViewControllerAnimated(true) { completed in
if completed {
presentingViewController?.presentViewController(controller, animated: true, completion: nil)
}
}
Also, make sure self.presentingViewController is not nil in the first place.
The reason nothing is happening is because self.presentingViewController? is nil.
If instead, you were using self.presentingViewController!, there would be an error stating Unexpectedly found nil while unwrapping optional value, which should always be avoided.
You are correct in using self.presentingViewController? instead of self.presentingViewController!, as it is much safer, but in order to fix this, you must make sure that self.presentingViewController? is not nil.
let presenting = self.presentingViewController
self.dismissViewControllerAnimated(true, completion: {() -> Void in
presenting?.presentViewController(controller, animated: true, completion: nil)
})

Switch between different Views in SWIFT

I read a lot of questions / answers in the stack overflow community about switching between different ViewControllers but I couldn't find the correct answer for my specific problem.
I'm using a NavigationViewController to "connect" all my different viewControllers (ViewController / TableViewController / CollectionViewController)
I have got some classes which aren't depending on a ViewController class. For example to to calculate anything in my "calculate" class.
I'm searching for an easy solution, to switch between all my ViewControllers. And I would like to decide in my "calculate" class e.g. to go one step back in my Navigation ViewController.
In the moment I use this:
Example to switch between two different ViewControllers:
let sb = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewControllerWithIdentifier("StartPage") as! StartPageView
self.presentViewController(vc, animated: true, completion: nil)
PROBLEM: This example only works in a ViewController class and the navigation bar disappears.
Example to go one step back in my NavigationViewController:
self.navigationController?.popViewControllerAnimated(true)
PROBLEM: This example only works in a ViewController class.
EDIT 1:
I found a nice solution to call all my viewControllers with this part of code:
let switchViewController = self.navigationController?.viewControllers[1] as! ScanTableView
self.navigationController?.popToViewController(switchViewController, animated: true)
How can I call this code in a non ViewController class?
Push the new view controller onto your existing navigation stack, rather than presenting it modally:
let vc = self.storyboard!.instantiateViewControllerWithIdentifier("StartPage") as! StartPageView
self.navigationController!.pushViewController(vc, animated: true)

iOS Swift, returning to the same instance of a view controller

I have a problem, where I have two view controllers A and B. View controller B has a map, with a route draw on it. I can move back and forwards between the two view controllers at the moment, but the B view controller is reset every time it loads. I think this is because I am using segues and it is creating a new instance of a View controller every time.
I have tried using the following code to solve this issue, but it is still not working. The views load correctly, but view controller B is still being reset
#IBAction func mapButton(sender: AnyObject){
let storyboard = UIStoryboard(name: "MainStoryboard", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("SecondViewController") as! UIViewController
self.presentViewController(vc, animated: true, completion: nil)
}
What am I doing wrong and how can I fix it? I want view controller B to stay in the memory along with the map and the route, so when a user returns he doesn't have to enter all of the information again.
You should create a variable in your class of type UIViewController and change your code to the following:
#IBAction func mapButton(sender: AnyObject){
if yourVariable == nil {
let storyboard = UIStoryboard(name: "MainStoryboard", bundle: nil)
yourVariable = storyboard.instantiateViewControllerWithIdentifier("SecondViewController") as! UIViewController
}
self.presentViewController(yourVariable, animated: true, completion: nil)
}
That way you create the viewController one time, save it and if you want to open it again present the previously created one.

dismissViewControllerAnimated Crashes EXC

I've been trying to present and dismiss a view controller programmatically and I keep running into EXC issues.
What is the proper way to present and dismiss a view controller other than using:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("Popup") as UIViewController
self.presentViewController(vc, animated: true, completion: nil)
and self.dismissViewControllerAnimated(true, completion: nil)
?
So far the app crashes when i run the function: dismissViewControllerAnimated
Please help, thanks!
Apparently, I had a NSNotification listener in the ViewController which caused the crash.
What I did was take it out and re-did the ViewController to populate the View Controller via a method rather than use a method linked to a NSNotification Listener.

Resources