Simulating a UINavigationController Pop - swift

I'm using a navigation controller and it works great. However, some custom buttons segue to new ViewControllers (not in the stack) and I don't like the push-type transition animation it uses.
GOAL:
I want to the transitions (described above) to mimic a nav-stack pop transition (where the current view slides to right, revealing the view underneath).
I've successfully simulated a nav-pop using the below code, but then after my buttons and nav-bar back button are super glitchy.
#IBAction func Page2_to_Page1_ButPush(sender: AnyObject) {
var curPage: UIViewController = self.storyboard!.instantiateViewControllerWithIdentifier("Page2_ID") as! UIViewController
var prevPage: UIViewController = self.storyboard!.instantiateViewControllerWithIdentifier("Page1_ID") as! UIViewController
self.navigationController?.pushViewController(prevPage, animated: false)
self.navigationController?.pushViewController(curPage, animated: false)
self.navigationController?.popViewControllerAnimated(true)
}
Can anyone supply a simple way to make my segues simulate a nav-pop?
Details:
X-Code 6.4
Swift
Storyboard

Here's the solution:
iOS Segue - Left to Right -
Simple, easy, works perfect. Add the "SegueFromLeft" class code shown in the link, select the segue you want to present from left, select custom, pointed it at "SegueFromLeft", and the animation is dead on.
Bonus: Even better, it syncs up with the navigation controller, so the nav "Back" button still works.

Related

New view controller showing up modally instead of full screen on iPads

As I want to have more control over actions of when someone could press a button for going to another view controller, I tried to step away from the navigation controller system.
At the moment, as I'm still just a starter in Xcode I'm struggling with opening a view controller and closing it.
I tried to open it with this code:
#IBAction func didTapGame(){
let vc = storyboard?.instantiateViewController(identifier: "Game_VC") as! Game_ViewController
present(vc, animated: true)
}
and on the iPhones it seemed legit, but on the iPad it appeared modally as a screen on top of the homescreen of the app and too small so you could just tap it away on the side.
How do you properly present a view controller in code in storyboard and how do you close it again with a backbutton as I tried the backbutton the same way, but it just added a new homescreen on top of everything which isn't desirable of course, Thanks!
It is difficult to answers without more context, but if you have a UINavigationController you can try this:
self?.navigationController?.pushViewController(viewController: vc, animated: true)

Unwind segue through navigation controller

I want have the back button on 'Saved Locations' to unwind segue to the 'Second View Controller', but not sure if I have to do anything different because it is embedded in navigation controller. I have linked the back button to the unwind function already in the storyboard. (ViewController is 'Saved Locations'). Currently, when clicking the back button, nothing happens.
The code below is in the SecondViewController.swift file
#IBAction func fromView(segue: UIStoryboardSegue){
if let sourceViewController = segue.source as? ViewController{
print("hi")
}
}
Segues work in context of the push/modal and popover segues. Your SavedLocations controller is embedded in a UINavigationViewController, but SecondViewController is not child of the same container. It's actually not very clear how you take the user to the SavedLocations from your storyboard screenshot but I'd like to propose embedding both controllers under the same navigation controller as possible. This is the the simplest and the cleanest way, as you don't even have to handle unwind seagues manually at all. "Plain" navigation is handled automatically in backward direction for you (unless you want to pop more than one controller in one go)

swipe action not popping to previous controller - what am I missing?

I have the UI Gesture Recognizer connected to my swift file and have this code to pop over to the previous controller. However, I'm not having luck atm. what am I missing?
#IBAction func leftswipe(_ sender: Any) {
[navigationController?.popViewController(animated: true)]
}
You need embed first viewController into UINavigationController and use "Show" or "Show Detail" segue`s type.
Try printing navigationController, it must be nil. Are you sure you have the first viewController is embedded in navigation controller and this viewcontroller is in the navigation controller stack? Also I noticed [] brackets in your code. Don't use that in Swift.

UINavigationBar loses tint color when I show a new UIView

I have added a tint to the UINavigationBar via the following lines of code in the AppDelegate:
let navBar = UINavigationBar.appearance()
navBar.barTintColor = mainColor
However when I go to a different view via a segue, I lose the color. View 2 isn't embedded in its own UINavigationController.
If I embed it in a nav controller it appears however if I go to View 3 from View 2, it too disappears.
I'm using 'Show' as the segue option.
I had used an #IBAction action to go from View 2 to View 3. That's why I had to replace
navigationController?.popViewControllerAnimated(true)
with the following:
self.dismissViewControllerAnimated(true, completion: nil)
I learned this via - Go back to previous view controller doesn't work

How can I go back to the initial view controller in Swift?

So I have a login view, after successful login it goes to the first view of a navigation controller, then the user can go deeper to a settings view and then to a logout view. This logout should take the user back to the login view (which is not part of the navigation controller). It works with this code:
let loginViewController = self.storyboard!.instantiateViewControllerWithIdentifier("Login") as? LoginViewController
self.navigationController!.pushViewController(loginViewController!, animated: true)
But the login view displays the navigation bar at the top, which it shouldn't do, maybe there is something other than self.navigationController!.pushViewController that I should be using?
SWIFT: You should use an unwind segue.
First of all, put the following line in your FirstViewController:
#IBAction func prepareForUnwind(segue: UIStoryboardSegue) {
}
The function actually doesn't have any code inside it.
Now, go to your storyboard and create an unwind segue for LogoutViewController by control-dragging from the yellow button to the Exit button. Like this:
Select the unwind segue created for FirstViewController.
Change the segue identifier:
Go to the code of LogoutViewController and just call the unwind segue normally:
self.performSegueWithIdentifier("unwindToViewController1", sender: self)
Swift 4
self.performSegue(withIdentifier: "unwindToViewController1", sender: self)
If you have a Navigation controller, from your your controller use:
self.navigationController?.popToRootViewControllerAnimated(true)
Look into unwind segueing if you are working with storyboards.
You just need to create unwind option in controller, that you want navigate to:
#IBAction func unwindToMe(segue: UIStoryboardSegue){}
Then create segue from storyboard.
And when you need to navigate back, just call the performSegue method with the unwind segue identifier that you just created.
If you want to do it only from code, than you just can write something like:
let loginViewController = self.storyboard?.instantiateViewControllerWithIdentifier("Login")
UIApplication.sharedApplication().keyWindow?.rootViewController = loginViewController
In this case, you will set your app to initial state.
try it
self.view.window?.rootViewController?.dismissViewControllerAnimated(true, completion: nil)
This will get you back to the beginning of the application flow.
Updated to Swift 4 (thanks #javaBeast)
self.view.window?.rootViewController?.dismiss(animated: true, completion: nil)
self.navigationController?.popToRootViewController(animated: true)
is the best option to go to first controller of navigation controller
and then dismiss the navigation controller
I recommend you to make a segue from one ViewController to another, instead of pushing your ViewController like that.
So first, you need to Ctrl + clic from your first ViewController to your login ViewController, and then in the attribute inspector your give it an Identifier.
Then, all you have to do is this :
self.performSegueWithIdentifier("yourIdentifier", sender: self)
Now, for the navigation bar, I suggest you to remove the navigation controller from the login view, and associate it to your first view. It would remove the navigation bar from your login view.