Changing view controllers programatically and using segues - ios

I am looking to replace this code:
let homeViewController = storyboard?.instantiateViewController(identifier: Constants.Storyboard.homeViewController) as? HomeViewController
view.window?.rootViewController = homeViewController
view.window?.makeKeyAndVisible()
This code is how I change my view controllers programatically and I have been told it works but is not the best to use.
My storyboard is currently set out like this:
Everything left of the navigation controller needs to be controlled programatically as I do not want segues from sign up and login to the main page. However everything right of the navigation controller, I want to be controlled with segues, however when I do this it always presents modally. And that is why I am using that code snippet to change View Controllers.
EDIT:
I want to use segues and a navigation controller because I want to use the toolbar

The problem is that you are loading HomeViewController as the root view controller:
let homeViewController = storyboard?.instantiateViewController(identifier: Constants.Storyboard.homeViewController) as? HomeViewController
view.window?.rootViewController = homeViewController
view.window?.makeKeyAndVisible()
Instead, you want to load a UINavigationController as the root. Give the navigation controller in your storyboard an ID (such as "mainNavController") and change your startup code to:
let navController = storyboard?.instantiateViewController(identifier: Constants.Storyboard.mainNavController)
view.window?.rootViewController = navController
view.window?.makeKeyAndVisible()
Now, HomeViewController will be loaded as that navigation controller's "root" controller, and your segues will "push" instead of "present".
Note: I'm assuming your current code (with the optional storyboard? and view.window?) already working correctly.

You can change the way segue's present view controllers in your storyboard. You can change it to cover full screen so that it isn't modal. There are attributes on the right side you can experiment with.

Related

Going to a navigation controller inside a Tab Bar

This is how my storyboard is laid out:
The first View controller on the left is the initial VC and this decides which VC to go to if you are signed in or not. I have not decided to implement a Tab Bar controller to have a tab bar. However I need a navigation controller going to each VC coming out of the tab bar.
If I use this code to navigate over, it shows a black screen (It worked fine before adding a Tab Bar Controller):
let mainNavController = storyboard?.instantiateViewController(identifier: Constants.Storyboard.mainNavController)
view.window?.rootViewController = mainNavController
view.window?.makeKeyAndVisible()
If I use this code, all of the segues show modally:
let viewController = storyboard?.instantiateViewController(identifier: Constants.Storyboard.homeViewController) as? HomeViewController
view.window?.rootViewController = viewController
view.window?.makeKeyAndVisible()
And as s last resort I tried to go straight to the Tab Bar controller but then I got this error:
Storyboard (<UIStoryboard: 0x600000e88840>) doesn't contain a view controller with identifier 'tabBarController'
So my problem is I want to navigate from a View controller programatically to the show the Tabbed VCs and use a navigation controller so all of the segued view controllers don't show modally.
(I have tried using individual Navigation Controllers for each of the tabbed vCs but that shows a black screen also)
This was the original with the tabbed VCs having individual Navigation Controllers:
And the error I got when trying to programatically go to that was
Storyboard (<UIStoryboard: 0x600000e88840>) doesn't contain a view controller with identifier 'tabBarController'
Even though it does

Swift - SWRevealViewController Left BarButtonItem not working after navigation

I have implemented SWRevealViewController into my project successfully. The side menu is a UITableView with different cells which navigate to differing view controllers. When I tap on the 'profile' cell it defaults to the LoginViewController, there the user will login in and, once verified, will go to the ProfileViewController. This leads to my problem, when I navigate to the ProfileViewController the Navigation bar button (on the left) does not work properly. Likewise, when I press the logout button (the right navigation bar button) it does navigate back to the LoginViewController, however, the menu button does not work.
My navigation functions are as follows:
func switchVC() { //Navigates to the profileViewController
let storyboard = UIStoryboard.init(name: "Login", bundle: nil)
let nav = storyboard.instantiateViewControllerWithIdentifier("Profile")
UIApplication.sharedApplication().keyWindow?.rootViewController = nav
}
func switchBack() { //Navigates back to the LoginViewController
let storyboard = UIStoryboard.init(name: "Login", bundle: nil)
let nav = storyboard.instantiateViewControllerWithIdentifier("Login")
UIApplication.sharedApplication().keyWindow?.rootViewController = nav
}
My storyboard is as follows:
Any help that you may be able to provide would be greatly appreciated. Thank you everyone!
Cheers
Your question is somewhat difficult to answer, but maybe this will help. In order for SWReveal View Controller to work, you always have to route to the main SWReveal Controller Scene for the menu button to work. For example, if my storyboard looked like
SWRevealViewController Scene --> Navigation Controller Scene --> Main View
and I routed back to the Navigation Controller Scene, the button would not work. You have to route back to the first Instance of the SWRevealController Scene that comes before the navigation / any other scenes you are trying to reach.
If you need to add another instance of SWRevealViewController Scene to make that work, just segue through the sw_front identifier to the navigation controller/ view controller you need the button to work in, and then segue it through the sw_rear identifier back to the same one instance of the menu.
Sorry if this answer is confusing, please let me know if I can clarify anything.

override screen when move another scree in swift

I am new in swift.I want to move one screen to another but problem is when I go to another screen,old screen overrides in new screen.
here is my code
dispatch_async(dispatch_get_main_queue()) {
let appsDelegate = UIApplication.sharedApplication().delegate
appsDelegate?.window!!.rootViewController = nil
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("launcherEntry") as! UINavigationController
appsDelegate?.window!!.rootViewController = nextViewController
}
If you use UINavigationController, you should push the second view(screen) onto the first one. Check out the offical guide.
According to your code old screen overrides because you have not a push a UIViewController into navigation controller.
Here you destroyee the exiting controller then set a new controller. So that previos controller is move from the memory.
Please show Apple docs for the UINavigationController.
Update:
Please use following code for set a root view controller then you can push view controller easily.
let navigationController:UINavigationController = storyboard.instantiateInitialViewController() as! UINavigationController
let rootViewController:UIViewController = storyboard.instantiateViewControllerWithIdentifier("ID_LoginVC") as! LoginVC
navigationController.viewControllers = [rootViewController]
self.window?.rootViewController = navigationController
As you are new , i will explain what will happen when your code will be executed.
App delegate will hold the current instance of our application. Setting root view controller is setting Main view controller of your application.
SO basically your code will replace the previous view controller with next one.
Now what you have to do,
We have Navigation controller to manage our navigation stack, that allow us to go back from where have initiated.
If you are Using storyboard , add your view controller into NavigationController, if you already know then ignore or follow this
SELECT your first view controller GOTO Editor in Xcode menu > Select EMBED IN option > NAVIGATION CONTROLLER. this will add your first view into navigation controller.
Now when you want to display next view controller, There are two ways to do so,
1)Using segue from Storyboard
Right click from view/button from where you want to show next view.
drag it to the next view controller and release the right click.
Select push
2)Programatically
you don't have to set root view controller, just push the next view controller in navigation controller you have
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("launcherEntry") as! UINavigationController
Above line will intimate the textview controller, now we have to push this view controller, we can achieve this with
self.navigationController?.pushViewController(nextViewController, animated: true)

UINavigationController Storyboard Hopping

I would like to know what code is required to traverse the storyboard from a UIViewController located at index N of a UINavigationController which is embedded in a UITabBarController, to a similarly embedded UIViewController.
I would also like all UIViewControllers to be popped in the source UINavigationController
Direct segues (as shown in red) do not fit my use case.
Swift please.
You can pop to the root view controller then change the selected index of the index of the tab bar controller then push whatever view controllers you need on the other navigation controller. For example:
let tabBarController = self.tabBarController;
let indexZeroNavController:UINavigationController = self.tabBarController?.viewControllers![0] as! UINavigationController
self.navigationController?.popToRootViewControllerAnimated(true)
tabBarController?.selectedIndex = 0
let newViewController = self.storyboard?.instantiateViewControllerWithIdentifier("New View Controller")
let otherNewViewController = self.storyboard?.instantiateViewControllerWithIdentifier("Other New View Controller")
indexZeroNavController.pushViewController(newViewController!, animated: true)
indexZeroNavController.pushViewController(otherNewViewController!, animated: true)
Beyowulf's approach used to be valid, but things have changed. In the viewController you wish to pop to, define an "unwind segue". example Once it's defined, you can drag from a button to "exit" and select that unwind segue.
The way unwind segues work has been completely reworked in xcode 7, so you don't have to worry too much about the view controller stack.

PresentViewController to a ViewController with a different NavigationController but on the same storyboard

I'm having trouble with a simple Xamarin Studio Storyboards concept. See screenshots below for visuals and see the downloadable source code here.
Let's say I have a NavigationController with MainViewController on it. This is visible in my storyboard. I want a button which, when pressed, brings up a new NavigationController with RedViewController. I also want RedViewController on the same storyboard as the MainViewController. In this project, I tried to do that but for some reason when I do a:
var myStoryboard = AppDelegate.Storyboard;
// Instatiating View Controller with Storyboard ID 'StuffViewController'
RedViewController = myStoryboard.InstantiateViewController ("RedViewController") as RedViewController;
RedViewController.ModalTransitionStyle = UIModalTransitionStyle.CoverVertical;
this.PresentViewController(RedViewController, true, null);
the RedViewController doesn't have it's Navigation controller with it. When presented RedViewController's Navigation Controller is null! What am I doing wrong there?
Now when I created a NavigationController & BlueViewController in a totally seperate storyboard it works fine. When I press the Blue Button it goes to the BlueViewController and correctly shows it's NavigationController. Why is this one working but the other one not? The only difference that I can see is that they are on separate Storyboards.
UIStoryboard storyBoard = UIStoryboard.FromName ("BlueStoryboard", null);
UIViewController controller = storyBoard.InstantiateInitialViewController () as UIViewController;
controller.ModalTransitionStyle = UIModalTransitionStyle.CoverVertical;
this.PresentViewController (controller, true, null);
ViewController that can present a new NavigationController & ViewController ViewController called "Red" with a navigation bar
When you instantiate your new view controller you need to instantiate the UINavigationController, not the RedViewController.
In the case of your 'blue' code you instantiate the initialViewController - which is the navigation controller that contains the Blue controller.
You want
RedViewNavigationController = myStoryboard.InstantiateViewController ("RedViewNavigationController") as UINavigationController;
where 'RedViewNavigationController' is the identifier for the navigation controller that the Red View Controller is embedded in.
If you want to present the red controller with its navigation controller, you should instantiate the navigation controller (which, in turn, will instantiate the red controller), and present it.

Resources