After sucessful signin i am opening Tabbar with follwing code
let mainView = UIStoryboard(name:"Main", bundle: nil)
let tabbar = mainView.instantiateViewController(withIdentifier: "Tabbar") as? Tabbar
tabbar?.modalPresentationStyle = .fullScreen
self.present(tabbar!, animated: true, completion: nil)
Its open Tabbar with first index selected but first ViewController also cover the save area ...
and switching between the TabbarItems make it work fine ...
I am not able to understand why this happening only in one ViewController on first time open ... and how to tackle that.
Also tried following code but did't work ...
self.edgesForExtendedLayout = []
Its not the proper solution its a kind of hack ... I told in Question that its get automatically fixed after switching between TabbarItems ... so i just added Two lines right after opening Tabbar VC.
tabbar?.selectedIndex = 1
tabbar?.selectedIndex = 0
And know the complete code seems like this.
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let mainView = UIStoryboard(name:"Main", bundle: nil)
let tabbar = mainView.instantiateViewController(withIdentifier: "Tabbar") as? Tabbar
appDelegate.window = UIWindow(frame: UIScreen.main.bounds)
appDelegate.window!.rootViewController = tabbar
appDelegate.window!.makeKeyAndVisible()
tabbar?.modalPresentationStyle = .fullScreen
self.present(tabbar!, animated: true, completion: nil)
tabbar?.selectedIndex = 1
tabbar?.selectedIndex = 0
Related
Hi I am struggling with rootViewController I left some code fragment with an explanation below, please let me know.
If I do it like below, it works and every things fine.
private func presentLogin() {
log.info("presenting login..")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let vc = storyboard.instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
vc.modalPresentationStyle = .fullScreen
appDelegate.window!.rootViewController = vc
present(vc, animated: false)
}
right after that if I execute the code below, ios shows nothing but white blank page..
private func presentMain() {
log.info("presenting main..")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let vc = storyboard.instantiateViewController(withIdentifier: "MainTabBarController") as! MainTabBarController
vc.modalPresentationStyle = .fullScreen
appDelegate.window!.rootViewController = vc
present(vc, animated: false)
}
but when I deleted the code
appDelegate.window!.rootViewController = vc
everything is fine.
In other words, the code below works only the first time.
appDelegate.window!.rootViewController = vc
why? what am I missing?, I don't understand..
It seems there are a lot of bugs concerning the exchange of the root view controller. Switching the root view controller is also a little uncommon way of "navigation". I would recommend a different approach:
Upon app startup, use a "launch" view controller. This is your root view controllers, and it stays to be your root view controller all the time
if login is required, present a login view controller
after successful login, dismiss the login view and go on
if logged in, present the main application's entry view
When a user launches the app from a push notification I present one view controller, then push another. My code to present the first VC is as follows
let mainStoryBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let homeNav: UIViewController = mainStoryBoard.instantiateViewController(withIdentifier: "HomeNavController") as! UINavigationController
let homePageTableVC = mainStoryBoard.instantiateViewController(withIdentifier: String(describing: HomePageTableViewController.self)) as! HomePageTableViewController
homePageTableVC.tipToPresent = tipDay
homeNav.addChildViewController(homePageTableVC)
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = homeNav
self.window?.makeKeyAndVisible()
The tipToPresent property is used by the homePageTableVC (in the viewDidLoad method) to then present the second VC, using this code:
if let tipDayToPresent = tipToPresent {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let tipVC = storyboard.instantiateViewController(withIdentifier: String(describing: TipViewController.self)) as! TipViewController
tipVC.dayOfTip = tipDayToPresent
tipToPresent = nil
navigationController?.pushViewController(tipVC, animated: true)
}
This works well, but when I press the back button to return to the homePageTableVC, the navigation bar is blank. The title image, menu button, and right bar button that normally show up are not visible.
Any help is appreciated.
Good if solution by #augie works. I would suggest you should not change navigation stack when you handle push notification deep link. It should behave same as it does in normal app launch. By that way you don't need to handle any edge case and no need to set up different window.
Solution: Whenever someone click on push notification dismiss all presented controller and popToRootViewController and then navigate to desired screen.
Can you try changing this
homeNav.addChildViewController(homePageTableVC)
to this
homeNav.setViewControllers([homePageTableVC], animated: false)
I believe the problem is how you are adding your table on the navigation controller. Instead of making it your navigation's root viewcontroller you are adding it as a child vc.
Changing your code like this should work:
let mainStoryBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
// Remove type UIViewController
let homeNav = mainStoryBoard.instantiateViewController(withIdentifier: "HomeNavController") as! UINavigationController
let homePageTableVC = mainStoryBoard.instantiateViewController(withIdentifier: String(describing: HomePageTableViewController.self)) as! HomePageTableViewController
homePageTableVC.tipToPresent = tipDay
// Set controllers instead of adding child
homeNav.setViewControllers([homePageTableVC], animated: false)
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = homeNav
self.window?.makeKeyAndVisible()
I would like to jump from a viewController to the first viewController related to Tab Bar Controller through code.
The tabBarController Scene has storyboard id tabView.
I'm working on this way:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: UITabBarController!
storyboard.instantiateViewController(withIdentifier: "tabView")
vc=storyboard.instantiateViewController(withIdentifier: "tabView") as! UITabBarController
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.present(vc as! UIViewController, animated: true, completion: nil)
}
But it loads only the first viewController (out of 5) without the tab bar related to. How can I solve it?
Oh, this code looks so wrong.
In your storyboard give and "tabView" ID to the TabBarController, not the ViewController inside it.
Why you are double instantiating ViewController? just do it once and assign it to the vc variable.
Why you've created delay before presenting the VC? It's some sort of workaround of something?
Working code:
let vc = storyboard.instantiateViewController(withIdentifier: "tabView") as! UITabBarController
self.present(vc, animated: true)
Use
(1)if you want to navigate from Appdelegate
let appDelegate = UIApplication.sharedApplication.delegate as! AppDelegate
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let tabBar = mainStoryboard.instantiateViewControllerWithIdentifier("TabBarController") as! TabBarController
appDelegate.window?.rootViewController = tabBar
appDelegate.window?.makeKeyAndVisible()
(2)if you want to navigate from viewcontroller which has root of navigation
self.navigationController?.pushViewController(tabBar, animated: true)
I'm running into this issue when I'm opening a new View Controller programmatically.
let controller = self.storyboard?.instantiateViewController(withIdentifier: "overViewScreen") as! OverviewViewController
controller.user = self.userObject
let navigationController = UINavigationController(rootViewController: controller)
self.present(navigationController, animated: true, completion: nil)
The structure of my project :
storyboard
On my storyboard the tab bar is shown onto the View Controller (with the table on the right), but when I run the app it looks like this :
enter image description here
I hope you guys can help me out!
Thank you.
You are presenting NavigationController without tab bar controller. You need to present TabBarController.
Give your TabBarController identifier and instantiate them just like you've done with controller
code from comment:
let tabVC = UIStoryboard(name: "NameOfYourStoryboard", bundle: Bundle.main).instantiateInitialViewController() as! UITabBarController
let navVc = tabVC.viewControllers.first as! UINavigationController
let vc = navVc.viewControllers.first as! OverviewViewController
vc.incorrectAuthorization = SettingsAuthorizationMethod.fingerprint
vc.user = self.userObject
present(navController, animated: true, completion: nil)
Ok, I managed to fix it like this :
let vc = self.storyboard?.instantiateViewController(withIdentifier: "TabBarController") as! TabBarController
vc.user = self.userObject
let nvc = UINavigationController(rootViewController: vc)
self.present(nvc, animated: true, completion: nil)
I made a seperate controller class "TabBarController", and added a property "user" to this class. In my "OverViewController" I can get the property as follows :
let tabBar: TabBarController = tabBarController as! TabBarController
user = tabBar.user
Thanks for the help!
I am using MMDrawerController to navigate through various views in my app one of which is a TabBarController which has 5 further views linked to each of its 5 bar items. Each of those 5 views have navigation bar items attached to them. The left bar Item on each of these 5 views toggles the LeftViewController (The view that I use as my drawer). I am using this code in my AppDelegate to achieve this
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var centerViewController = mainStoryboard.instantiateViewControllerWithIdentifier("TabBarController") as! TabBarController
var leftViewController = mainStoryboard.instantiateViewControllerWithIdentifier("LeftViewController") as! LeftViewController
var leftsideNav = UINavigationController(rootViewController: leftViewController)
var centerNav = UINavigationController(rootViewController: centerViewController)
centerContainer = MMDrawerController(centerViewController: centerViewController, leftDrawerViewController: leftViewController)
centerContainer!.closeDrawerGestureModeMask = MMCloseDrawerGestureMode.PanningCenterView
and I am calling this method when the left bar buttons are tapped on the 5 ViewControllers
#IBAction func leftButtonTapped(sender: AnyObject) {
var appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.centerContainer!.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)
}
Works perfectly so far.
Now I have a tableView in my LeftViewController in which I wish to achieve the following behaviour - clicking on the first row navigates us to the TabBarController while the second row takes us to another ViewController and with withFullCloseAnimation set to true.
Here is the code in the didSelectRowAtIndexPath method of the LeftViewController's tableView
var appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var centerViewController = mainStoryboard.instantiateViewControllerWithIdentifier("TabBarController") as! TabBarController
var centerNav = UINavigationController(rootViewController: centerViewController)
appDelegate.centerContainer?.setCenterViewController(centerNav, withFullCloseAnimation: true, completion: nil)
appDelegate.centerContainer!.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)
break;
This makes the navigation bar items of the 5 views in the TabBarController disappear. It works fine if I use this -
var appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.centerContainer!.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)
break;
The last bit of code makes me think it is initiating the TabBarController all over again rather than 'restoring' the one that had already been initalised. Is that so?
What should be the right way to achieve this?
Sorry for the length of the question (just increased it further by typing this)
I added .navigationController
in the didSelectRowAtIndexPath indexPath: NSIndexPath)
appDelegate.centerContainer!.centerViewController centerViewController.navigationController
break;