Get custom NavigationController class from custom UIViewController - ios

I am trying to implement the side navigation menu (one that we have in Android) in iOS App.So far i tried the following:-
AppDelegate.swift :-
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var bridge: RCTBridge!
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let sb = UIStoryboard(name: "mystoryboard", bundle: Bundle.main)
let rootViewController: UIViewController =
sb.instantiateViewController(withIdentifier:
"NativeLabelSwiftViewController") as UIViewController
let navigationController = UINavigationController(rootViewController:
rootViewController)
window = UIWindow(frame: UIScreen.main.bounds)
window!.rootViewController = navigationController
window!.makeKeyAndVisible()
return true
}
The above is my AppDelegate class since it is a React Native project we have the generated code as well.Here added the following code to instantiate my rootViewClass(NativeLabelSwift) by following code :-
let sb = UIStoryboard(name: "mystoryboard", bundle: Bundle.main)
let rootViewController: UIViewController =
sb.instantiateViewController(withIdentifier:
"NativeLabelSwiftViewController") as UIViewController
NavigationLabelSwiftViewController.swift(Custom View Class) :-
class NativeLabelSwiftViewController: UIViewController{
var bridge: RCTBridge!
override func viewDidLoad() {
super.viewDidLoad()
title = "Production Tracking"
let btn2 = UIButton(type: .custom)
btn2.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
btn2.addTarget(self,
action:#selector(NativeLabelSwiftViewController.
onBtn2Clicked.(_:)), for: .touchUpInside)
let item2 = UIBarButtonItem(customView: btn2)
self.navigationItem.setLeftBarButton(item2, animated: true)
}
#IBAction func onBtn2Clicked(_ sender: UIBarButtonItem) {
if let navViewController = self.navigationController as?
NavigationController {
// navigation view controller is available
}
else{
// navigation view controller not available
}
}
}
The Navigation Controller has a UIViewController class (NativeLabelSwiftViewController) that has a button in Tab Bar.On Press of the Button i need to access the Navigation Controller method.But i am not able to get the navigation controller using the below code :-
let navViewController = self.navigationController as?
NavigationController; //this is NIL
But
let uiViewController = self.navigationController as?
UINavigationController; //this is not NIL

You are not referring your custom navigation controller in the AppDelegate. You used UINavigationController(rootViewController: rootViewController).
You if you want to use the storyBoard NavigationController, In AppDelegate use -
let nav = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "NavigationController") as! NavigationController
window = UIWindow(frame: UIScreen.main.bounds)
window!.rootViewController = nav
window!.makeKeyAndVisible()
return true
Note: Don't forget to put an Identifier for the StoryBoard NavigationController.

Related

Navigation Bar Disappears Change Root ViewController and then reassign

I've made the launch screen the root view while my app makes a request to firebase and then reassign the root view once the request has been completed. Unfortunately when I do this my navigation bar disappears or is covered up by the new root view. When I run the simulator I can see the navigation bar briefly and then it get covered up by my TableViewController. How do I keep this from happening?
Here is my code from the AppDelegate where I make all of this happen:
var window: UIWindow?
let searchManager = SearchManager()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
makeRootViewLaunchScreen()
FirebaseApp.configure()
searchManager.getMosaicTitles { results in
self.searchManager.listOfMosaics = results
self.stopDisplayingLaunchScreen()
}
// Adds border to bottom of the nav bar
UINavigationBar.appearance().shadowImage = UIImage.imageWithColor(color: UIColor(red:0.00, green:0.87, blue:0.39, alpha:1.0))
// Override point for customization after application launch.
return true
}
func makeRootViewLaunchScreen() {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "LaunchScreen", bundle: nil)
let viewController = mainStoryboard.instantiateViewController(withIdentifier: "launchScreen")
UIApplication.shared.keyWindow?.rootViewController = viewController
}
func stopDisplayingLaunchScreen() {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = mainStoryboard.instantiateViewController(withIdentifier: "centralViewController") as? SearchResultsTableViewController
viewController?.searchManager = searchManager
UIApplication.shared.keyWindow?.rootViewController = viewController
UIApplication.shared.keyWindow?.rootViewController?.navigationController?.isNavigationBarHidden = false
}
As you can see I tried to use UIApplication.shared.keyWindow?.rootViewController?.navigationController?.isNavigationBarHidden = false to force the navigation bar to appear but it doesn't. My app still looks like this:
You are setting a UIViewController as your Root controller. What you want to do is set a UINavigationController as your Root controller.
Either create a new navigation controller in your storyboard and load that one instead of loading "centralViewController", or modify your function like this:
func stopDisplayingLaunchScreen() {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
if let viewController = mainStoryboard.instantiateViewController(withIdentifier: "centralViewController") as? SearchResultsTableViewController {
viewController.searchManager = searchManager
// create a new UINavigationController
let newNavVC = UINavigationController()
// set the "root" VC of the NavVC to your SearchResultsTableViewController
newNavVC.setViewControllers([viewController], animated: false)
// use the new NavVC as the new rootViewController
UIApplication.shared.keyWindow?.rootViewController = newNavVC
UIApplication.shared.keyWindow?.rootViewController?.navigationController?.isNavigationBarHidden = false
}
}
Note: not tested, but this should get you on your way.
Edit: Another approach...
Instead of swapping the root controller of the key window, create a ViewController that indicates you are initializing / retrieving your data. That VC can be the "root" of a Navigation Controller.
Put your searchManager.getMosaicTitles function in that VC. When it has finished, replace the current "launch" controller in your Nav Controller with your TableVC. It will look something like this:
// note: searchManager will have to be a reference back to AppDelegate.searchManager
searchManager.getMosaicTitles { results in
self.searchManager.listOfMosaics = results
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
if let viewController = mainStoryboard.instantiateViewController(withIdentifier: "centralViewController") as? SearchResultsTableViewController {
viewController.searchManager = searchManager
// replace the current Nav VC stack with the new SearchResultsTableViewController
self.navigationController.setViewControllers([viewController], animated: false)
}
}
To prevent the lag between when the navigation bar controller appears and the tableView appears check out the following. Prevent navigation bar from disappearing without lag

How to programmatically add a second view in swift 3

Im trying to switch to a second view from a button on the first view, and do this programmatically (not using the traditional way of switching between views using a segue on the storyboard)
My current app delegate:
import UIKit
#UIApplicationMain
public class AppDelegate: UIResponder, UIApplicationDelegate {
public var window: UIWindow?
public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = UINavigationController(rootViewController: ViewController())
return true
}
Button function in first view controller that when pressed should just switch to new view:
func signupAction (sender: UIButton!){
}
I already have the new viewcontroller file created:
class Signup: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.cyan
}
}
Basically, I'm trying to achieve the button in the first viewcontroller transitions to this signup viewcontroller.
If you are in a UINavigationController you could push the Signup view controller to the navigation stack this way:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let signUpViewController = storyboard.instantiateViewController(withIdentifier: "signUpViewController") as! Signup
navigationController?.pushViewController(signUpViewController, animated: true)
If you are not in UINavigationController and want to present it, you can do it this way:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let signUpViewController = storyboard.instantiateViewController(withIdentifier: "signUpViewController") as! Signup
self.present(signUpViewController, animated: true, completion: nil)
Note: Don't forget to set the identifier of your view controller in the storyboard.

How can I embed my navigation controller into my tab bar controller programmatically in Swift Xcode 8.2?

I have been teaching my self how to develop and I got to the point to where I need guidance from experts. I created some of the user interface programmatically using the MVC structure. My question is how can I embed my navigation controller into my tab bar controller so my tab bar controller can be on every screen. I made the tab bar controller in main.storyboard and referenced it in the View controller I named Home Controller.
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let tabViewController = storyboard.instantiateViewController(withIdentifier: "TabBar")
self.present(tabViewController, animated: true, completion: nil)
The code above is in the view did load function. I was wondering do I need to change up the root view controller in my app delegates?
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
let layout = UICollectionViewFlowLayout()
window?.rootViewController = UINavigationController(rootViewController: HomeController(collectionViewLayout: layout))
This is in my finished launched func.
Use following lines
var navigationController = UINavigationController(rootViewController: viewController));
tabBarController.viewControllers = [navigationController,firstViewControllersecondViewController, ]
create a separate UITabBarController class and initialize it in AppDelegate like this:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = MyTabBarController()
window?.makeKeyAndVisible()
return true
}
and the custom tabBarController
import UIKit
class MyTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
self.tabBar.barTintColor = UIColor.black
self.tabBar.tintColor = UIColor.white
self.tabBar.unselectedItemTintColor = UIColor.white.withAlphaComponent(0.4)
let firstViewController = FirstViewController()
let firstViewTabBarItem = UITabBarItem(title: "First", image: UIImage(named: "calculator"), selectedImage: UIImage(named: "calculator"))
firstViewController.tabBarItem = firstViewTabBarItem
firstViewController.tabBarItem.tag = 0
let historyViewController = HistoricDataViewController()
historyViewController.tabBarItem = UITabBarItem(tabBarSystemItem: .history, tag: 1)
let tabBarList = [calculateViewController, historyViewController]
viewControllers = tabBarList.map{UINavigationController(rootViewController: $0)}
}
}
Hope this example helps.

Swift - UINavigation Controller becoming nil

I have a problem with my UINavigationController when I try to push another controller.
AppDelegate
let testViewController:ProximityQuestionsIntroductionViewController = ProximityQuestionsIntroductionViewController();
self.navController = UINavigationController(rootViewController: testViewController);
self.window = UIWindow(frame: UIScreen.mainScreen().bounds);
self.window!.rootViewController = navController;
self.window!.backgroundColor = UIColor.whiteColor();
self.window!.makeKeyAndVisible();
return true
ProximityQuestionsIntroductionViewController
class ProximityQuestionsIntroductionViewController:UIViewController {
// Controls
var proximityIntroductionView:ProximityQuestionsIntroductionView!;
// Load components when the view is loaded
override func viewDidLoad() {
super.viewDidLoad();
print("nav in viewDidLoad : \(self.navigationController)");
//Hide Nav bar
self.navigationController?.navigationBarHidden = true;
// Set view
self.proximityIntroductionView = ProximityQuestionsIntroductionView(frame: self.view.frame);
self.view = self.proximityIntroductionView;
}
func start(){
print(self);
print("start in controller");
let nextController = ProximityQuestionsProgressViewController();
print("nav in start : \(self.navigationController)");
self.navigationController?.pushViewController(nextController, animated: true);
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
I call start from my ProximityQuestionsIntroductionView when a button is clicked.
In the log I see "nav in start : nil" and the controller doesn't change.
For more info :
self is really the ProximityQuestionsIntroductionViewController.
the navigation bar is really hidden
So the navigation controller is ok in viewDidLoad but not in the other function.
Can someone tell me why ?
Thanks!
EDIT : AppDelegate
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewControllerWithIdentifier("ProximityIntroduction");
self.navController = storyboard.instantiateViewControllerWithIdentifier("NavigationController") as! UINavigationController;
self.navController?.setViewControllers([initialViewController], animated: false)
self.window?.rootViewController = navController;
self.window?.makeKeyAndVisible();
I add navigation Controller to the story Board and change the ID. But I still have a nil value for the UINavigationControllerin the function start
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewControllerWithIdentifier("ProximityQuestionsIntroductionViewController")
navigationController = UINavigationController.init(rootViewController:initialViewController )
navigationController?.setViewControllers([initialViewController], animated: false)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
Put Story board id for this ProximityQuestionsIntroductionViewController
You must mark the window and navController variables as optional:
var window : UIWindow?
var navController : UINavigationController?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
let testViewController:ProximityQuestionsIntroductionViewController = ProximityQuestionsIntroductionViewController();
self.navController = UINavigationController(rootViewController: testViewController);
if let window = window {
self.window = UIWindow(frame: UIScreen.mainScreen().bounds);
self.window!.rootViewController = navController;
self.window!.backgroundColor = UIColor.whiteColor();
self.window!.makeKeyAndVisible();
}
return true
}
If you created the project from an Xcode template:
Remove the key-value pair for key "Main storyboard file base name" from Info.plist.
Delete the storyboard file Main.storyboard.
The problem came from the view.
Doing this :
// Set view
self.proximityIntroductionView = ProximityQuestionsIntroductionView(frame: self.view.frame);
self.view = self.proximityIntroductionView;
causes the problem. I don't know exactly why but putting all the UIView in the controller directly solved the problem.

How to use Tab Bar Controller in my AppDelegate.swift

How to use Tab Bar Controller in my AppDelegate.swift
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var centerContainer: MMDrawerController?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
let rootViewController = self.window!.rootViewController
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
// Centre View Controller
let centerViewController = mainStoryboard.instantiateViewControllerWithIdentifier("ViewController") as! ViewController
// left view Controller along with centre view controller
let leftViewController = mainStoryboard.instantiateViewControllerWithIdentifier("LeftSideViewController") as! LeftSideViewController
// Right view Controller along with centre view controller
let rightViewController = mainStoryboard.instantiateViewControllerWithIdentifier("RightSideViewController") as! RightSideViewController
let leftSideNav = UINavigationController(rootViewController: leftViewController)
let centerNav = UINavigationController(rootViewController: centerViewController)
let rightNav = UINavigationController(rootViewController: rightViewController)
centerContainer = MMDrawerController(centerViewController: centerNav, leftDrawerViewController: leftSideNav,rightDrawerViewController:rightNav)
centerContainer!.openDrawerGestureModeMask = MMOpenDrawerGestureMode.PanningCenterView;
centerContainer!.closeDrawerGestureModeMask = MMCloseDrawerGestureMode.PanningCenterView;
window!.rootViewController = centerContainer
window!.makeKeyAndVisible()
return true
}
}

Resources