NavigationController nil with Material - ios

I have this in appDelegate:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window = UIWindow(frame: UIScreen.mainScreen().bounds)
let nav = NavigationViewController(rootViewController: MenuViewController(rootViewController: FeedVC()))
window?.rootViewController = SideNavigationController(rootViewController: nav, leftViewController: LeftVC(), rightViewController: nil)
window?.makeKeyAndVisible()
}
This works fine. My FeedVC is displayed and I can access the LeftVC with SideNavigationController. (Btw, is it a good way of doing it ?)
Then in my FeedVC class, I want to add titleLabel (navigationItem) to the navigationBar but navigationController is nil !
So I think my FeedVC is not embed in NavigationController. But I'm not using storyboard for this. How can I do this programmatically and take in count that there is also a SideNavigationController at the very top...
Thanks for helping!

Yes, all looks good, except, you do not need to set the rightViewController to nil. You can leave it out completely.
The issue with the titleLabel is that your FeedVC is a child of the MenuViewController. The MenuViewController is a child of the Nav, so the navigationItem should be set in the MenuViewController for this reason. You could flip the MenuViewController and NavigationController relationship, so that the Nav is a child of the Menu. Then you would be able to set the FeedVC navigationItem accordingly.
Hope that helps :)
Also, the framework is Material, not Material Kit. Might be better for search to correct that :)

Related

How to set a UITabBarController as rootViewController from Storyboard

Short question:
How can I launch and make a UITabBarController be the rootViewController of my app after starting with a Storyboard?
Long question:
I'm not a swift expert, but I managed to create a complete app using XIBs from the beginning. Now I need my app to start with a Storyboard as a new requirement to post updates to the appstore from 01/07/2020, but I never used it to build my views. It was easy to modify my app to have my Storyboard as an entry point, but the problem is that my initial view today is a TabController, and I don't know how to navigate from my initial Storyboard to my TabController.
My AppDelegate today works something like this:
var window: UIWindow?
func application(_application: UIApplication, didFinishLauchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
// initiate UINavigationControllers and UITabBarController here...
tabController.viewController = [nav1, nav2, nav3, nav4]
tabController.modalPresentationStyle = .fullScreen
self.window!.rootViewController = tabController
self.window!.makeKeyAndVisible()
}
All my attempts ended with a white screen after showing my Storyboard without showing my TabBar.
One of these attempts was this:
override func loadView() {
super.loadView()
// initiate tabController the same way I did in the AppDelegate
UIApplication.shared.keyWindow?.rootViewController = tabController
}
Check the value "Is initial View Controller" for it.

How to automatically navigate to a screen on start-up

When developing an app, if I only want to test one screen, say, the third tab of a tab view, how would I make the app navigate there on start up?
I think a good solution is use a UI test to automatically navigate to the correct place in the app. Pausing on a breakpoint at the end of the test leaves the app to be played with manually.
rootViewController of window property in AppDelegate will be the first view controller shown on screen. you can make it by programming or using storyboard
by programming:
if NavigationController is the rootViewController of your window, put your own viewController in the first place (index at 0) of NavigationController's viewControllers which is an array. it will be on screen by default.
customNavigationController.viewControllers = [yourViewController]
or simply set your viewController to the rootViewController to the window property in appDelegate
AppDelegate.swift:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.main.bounds)
// window?.rootViewController = CustomTabBarViewController()
// customViewController will show on screen by default.
window?.rootViewController = CustomViewController()
window?.makeKeyAndVisible()
return true
}
by interface builder:
check your viewControlelr's attributes inspector panel, and check "is Initial View Controller" option, then you can see a simple arrow attached to this view controller.
or:
add identifier to your viewController, and fetch it from storyBoard, then set it to the rootViewController of the window object in appDelegate
let testController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "testController") as! TestController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window?.rootViewController = testController

SideNavigationController - Replace rootViewController of NavigationController

I'm using the Material Framework by CosmicMind. Currently I'm trying to replace the ViewController once a row is selected in the SideNavigationController. Unfortunately I can't figure out how to do this. There're similar question here on StackOverflow (#1) unfortunately the solutions don't work for me.
Following my code in the AppDelegate.swift class:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let myViewController = storyboard.instantiateViewControllerWithIdentifier("MyViewController")
let navigationController: NavigationController = AppNavigationController(rootViewController: myViewController)
let sideNavigationController: SideNavigationController = SideNavigationController(rootViewController: navigationController, leftViewController: AppLeftViewController())
// further code
return true
}
With this code everything works fine. The ViewController (MyViewController) is shown.
Now I'm trying to replace the MyViewController with MySecondViewController however this doesn't work. Following the code I've been using:
sideNavigationController?.transitionFromRootViewController(MySecondViewController())
The result is that the Toolbar disappears and I can't close the SideNavigationController anymore. So I've tried the following:
let navigationController: NavigationController = AppNavigationController(rootViewController: MySecondViewController())
sideNavigationController?.transitionFromRootViewController(navigationController)
With this code the Toolbar is visible once again but the problem with the SideNavigationController remains -> means: It can't be closed.
tl;dr
How do I replace the rootViewController of the NavigationController properly?
The NavigationController is a subclass of UINavigationController. So changing the rootViewController is as iOS made it. For example:
navigationController?.pushViewController(MySecondViewController(), animated: true)
The SideNavigationController offers the ability to transition its rootViewController. This is different, as the SideNavigationController uses child UIViewControllers and swaps them when asked. For example:
sideNavigationController?.transitionFromRootViewController(MySecondViewController())
Sometimes, people use the sideNavigationController to early. For example, you instantiate a new UIViewController, and place the sideNavigationController code in the videDidLoad method. This won't work since the new UIViewController was not yet added to the sideNavigationController view hierarchy. To solve this, use the viewWillAppear method.
The last situation to consider is when you want to load a new UIViewController in the rootViewController of the NavigationController from the sideNavigationController. In order to do this, and let's consider that the sideNavigationController's rootViewController is the NavigationController, you would need to do this:
(sideNavigationController?.rootViewController as? NavigationController)?.pushViewController(MySecondViewController(), animated: true)
This should help you out :)

How can I change my initial View Controller when the user accepts the EULA

I hope this is a simple question. I have not found anything in SO that seems to fit what I'm trying to do. I am working on my first ever project so much of this is still quite new to me. The code I have pasted is from a test project I'm using before I add code to my real one.
My initial VC is the EULA. When the user accepts, I want to change the initial VC to the log in view. In this test project, I have two views with an IBAction for a Bar Button Item that will segue the project from VC to VC2. I am trying to set up code to change the initial VC in the AppDelegate with
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
let storyboard = UIStoryboard(name: "View Controller", bundle: NSBundle.mainBundle())
let licenseAccepted = ?
var vc: UIViewController?
if !licenseAccepted {
vc = storyboard.instantiateViewControllerWithIdentifier("View Controller2")
} else {
vc = storyboard.instantiateInitialViewController()
}
window = UIWindow(frame: UIScreen.mainScreen().bounds)
window?.rootViewController = vc
window?.makeKeyAndVisible()
return true
}
but this is not working. First, let licenseAccepted = ? is not correct. I found that in another set of code and I thought it might work, but no. Also, how do I set a var for if the user accepts the license in the AppDelegate? Should that be done in the initial VC, the second VC that will become the initial VC or somewhere else?
I am using Xcode 7.1 and Swift2 if that helps.
I may be way off base or I may be a keystroke or two away. I am just not getting my head around this. Your assistance will be appreciated.

I would like to embed UINavigationController with UITableViewController which is the sub-view of UITabBarViewController by programmatically in Swift

Recently, I want to make an App for self-study and that App looks like Contacts App in iOS. First, I have two UITableViewControllers connecting to UITabBarViewController. Then I want to embed UINavigationController with those 2 tableviews by coding (In this case, I don't want to embed it in Storyboard by design). But I'm stuck with it. Here is my code in AppDelegate
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let tabBar : UITabBarViewController = UITabBarViewController()
let tableView1 : UITableViewController = UITableViewController()
let nav = UINavigationController(rootViewController: tableView1)
let tableView2 : UITableViewController = UITableViewController()
let nav2 = UINavigationController(rootViewController: tableView2)
tabBar.viewControllers = [nav, nav2]
self.window?.rootViewController = tabBar
return true
}
And the result always displays the first tableView1. How can I make it to display two tab options(on the bottom of the view) in UITabBarViewController? If I make it by designing in Storyboard, I'm sure it will work fine. But by coding, I've no idea how to fix it.
Please kindly guide me. Thanks in advance!
There is no UITabBarViewController in UIKit. It is called UITabBarController. Your ViewControllers need to have NavigationItems. If you display them like in your code you will have a Tabbar on bottom but without anything visible on it. In your case the NavigationControllers are the ones where you need to define nav.navigationItem.title = ...
EDIT:
and I realized you are not initializing the window. This is not related to your other problem but you would not see anything with your code. So you have to change it to:
self.window = UIWindow(frame: UIScreen.mainScreen().bounds);
self.window?.rootViewController = tabBar
self.window?.makeKeyAndVisible();

Resources