Is there a way to unload a UITabBarController when it is popped off the stack of a UINavigationController, so that it is reloaded fresh when pushed back on the stack? I need to clear all of the data in all of the view controllers in the tab bar.
I've tried various methods of iterating through the tab bar's view controllers and setting each to nil, and setting the tab bar's view to nil, and I've also tried sending the didReceiveMemoryWarning message to each of the views.
In my main nib file (MainWindow.xib), I have a UINavigationController and a UITabBarController. Both are wired up to the app delegate as IBOutlets to ease in automatically loading the controllers, especially the tab bar controller.
The nav controller first loads another view as its root view, and when the user taps a button, the UITabBarController is pushed onto the UINavigationController stack.
This all works fine.
Now I want to be able to pop the UITabBarController off the nav controller stack, so the root view of the nav controller is redisplayed, and have it reset all of the data on all the views in the UITabBarController while it is hidden (off the stack).
From one of the view controllers in the tab bar controller, I can call [self.tabBarController.navigationController popToRootViewController:YES] and that works fine.
But how do I unload and reload all of the UITabBarController's views?
You should be able to re-init the view controllers and pass them into your tabBarController's setViewControllers: method.
Related
I'm working on a project which has multiple view controllers stacked in a navigation controller, similar to this:
https://youtu.be/yl2m4fDOLQo
I fear that I may end up stacking too many view controllers in one navigation controller. I understand that once there are more than 3 view controllers stacked in a navigation controller, the views are presented "modally"
First of all, what is a "modal" presentation? I looked it up in Swift documentation but I'm having some trouble understanding how it differs from the navigation stack. Second, if there is a problem, is there any way around it?
I'm new to this so help is much appreciated,
Nick
I understand that once there are more than 3 view controllers stacked in a navigation controller, the views are presented "modally"
This is false. You can have as many view controllers in a navigation stack as your app needs, as long as the device has enough memory. View controllers in a navigation stack have a navigation bar (technically, this is part of the navigation controller), a back button and (hopefully) a swipe-right gesture that allow the user to go back "up" the stack. You add a view controller to the stack by calling pushViewController(animated:) and remove it by calling popViewController(animated:) on the navigation controller.
A modal view controller exists outside of the navigation stack. It does not have a navigation bar because it's not in a navigation controller. You are responsible for adding some way to dismiss the modal, such as tapping a close button placed manually in the view controller's view somewhere. You can even add a navigation bar instance manually and put a close button in it. You show a modal by calling present(_:animated:completion:) on the currently-displayed view controller and dismiss it by calling dismiss(_:animated:completion:).
My application is view based app. First view is login view. After login view i have MainMenuCcontroller which has a tabBarController:
#interface RunnoMainMenuController : UIViewController {
IBOutlet UITabBarController *tabBarController;
}
From login view controller, i am going to MainMenuController using this line of code:
[self presentModalViewController:mainMenu animated:YES];
this controller has 4 tabs. Now i need to do some stuff in viewWillAppear of a tabBarItem. viewWillAppear is not called when i tap a tabBarItem. I have a button in one of those tabBarItem's view which pops up a table view controller using presentModalViewController. This tableView uses dismissModalViewControllerAnimated:YES to disappear it. When i pop up this tableview and dismiss it then viewWillAppear of every tabBarItem works fine. If i will dismiss modalViewController in MainMenuController then it will again go back to login view. How can i dismiss modalViewController without leaving current view or any other solution? Thanks in advance.
You may need to consider how your views are presented. The tab bar controller should always be the window's root view controller. From the Apple docs:
When deploying a tab bar interface, you must install this view as the
root of your window. Unlike other view controllers, a tab bar
interface should never be installed as a child of another view
controller.
Rather than present your login view as the root view and the tab bar as a modal view controller, try it the other way round. The tab bar controller as root, with the login view as presented as a modal view controller from the view controller of whichever tab is shown initially. Dismissing this will then reveal the tab bar controller.
I have a screen in my iPhone application where i have to load multiple kinds of data simultaneously. To simplify my code, I created separate view and loaded separate view controllers in them to handle each set of data. The blue rectangle on the top has a separate VC and the blue square(ish) below it has another VC that has a navigation controller. All is going well until I suddenly need to push a viewcontroller onto my stack in one VC if user taps on the view that is handled by a different VC.
You could add a property to each "sub" view controller where you could set a UINavigationController. Set the UINavigationController from the "container" view for each "sub" view controller and use this navigation controller instance to push other view controllers.
I have an iPhone / iPad application that manages its numerous view controllers via a UINavigationController and UITabViewController. The UINavigationController handles the majority of the user interaction and the UITabViewController handles user settings/preferences.
My app delegate initializes the UINavigationController and pushes the first view controller. Settings (the UITabViewController) can be accessed via a button on the navigation controller's menu bar; the user can return to the main application (the UINavigationController) via a button on the UITabViewController.
My question is: what should I be doing with the UINavigationController (and its stack of view controllers) when I show the UITabViewController and vice-versa? Is there any reason to remove/release/recreate each parent controller as the user switches between the two, or should I be adding/removing each parent controller's view to my app's window?
It seems that the first option would be more mindful of memory/resources, however these benefits might get overshadowed by the processing cost to re-alloc/init the view controllers each time.
Thanks.
You do not have to manage the navigation controller's stack manually. What I would do is present your settings view controller as a modal view. You would do this at the navigation controller level.
Assume that settingsViewController is a property of your main view controller.
self.settingsViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal
[self.navigationController presentModalViewController:self.settingsViewController animated:YES];
I assume you mean UITabBarController.
If your navigation view would show up in the tab view for a tab item, I would suggest let the tab bar controller to be the root view controller of your application (and therefore always seen in the app).
If your navigation view is the main view, and the user simply opens up the tab bar view for settings etc. and will return for the navigation view, then modally presenting the tab bar controller is the right way.
In the first case (the navigation controller IN the tab bar controller), you would not care for adding/removing or allocating/releasing views as the UIKit will manage it for you.
In the second case you may create a tab bar controller when you want to show it. presentModalViewController will retain the view controller so you can release it immediately after you send the message. If you want to hold the view controller then you create one when the application is loaded and retain it in the navigation controller (and the navigation controller will always remain in the memory).
I have a Navigation Controller with a root table view which has several links. Tapping each link moves to the next view (by pushing it to the navigation controller's stack). But suppose that in that "next view", I have a UIButton that should take me further to another view (by pushing on to the same navigation controller's stack)...
View Controller-->first view-->second view-->third view..........
Now, I can easily access the Navigation Controller when I deal with the first view (and successfully push it to the Navigation Controller's stack) because it has been instantiated in the same file itself. What my real doubt is--How do you access a Navigation Controller in a far off view controller (eg, the third view or fourth view etc)? Please note that I am not using any separate delegate. All the Navigation Bar methods have been implemented in one file and connected to the Navigation Controller via an outlet.
When you push a ViewController onto a NavigationController the ViewController will automatically have it's navigationController property set. This means you can access the same NAvigationController no matter where you are in the stack.
-Update-
navigationController
In every UIViewController you can access that property.
So to in any other UIViewController that has been pushed onto the stack you should be able to just do this:
[self.navigationController pushViewController:othercontroller animated:YES];
Look at the documentation for UIViewController to see what other magic properties you have available.