I have several tabs in my tab bar controller and only one (the first one) for which I would need an automated reload each time I select its tab (and also when the app come back to the foreground).
I did not find how to do this, do I need to recreate the tab bar controller manually each time ? Do I need to add a new set of view controllers to the tab bar controller ?
Thanks for your help
Would it make sense to have a updateView functio that you can call in viewWillAppear on that particular view that ensures everything is up-to-date each time the view is set to appear?
If your UIViewController is a UITabBarControllerDelegate it will get this callback, which is what you want, I believe:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
Simply return YES after calling your updateView method.
Related
I have tabbar based application, I want to start each time tab is pressed to start with first view they are associated with. Problem is it starts with first view when its a start of application but while using application i may navigate deep in to one tab and now what to do if i want to start it again with main view associated with that tab which is pressed?
You can use the tabbar delegates to override this behaviour. The UITabBarControllerDelegate is documented here:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UITabBarControllerDelegate_Protocol/Reference/Reference.html
You would want to look at:
tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
Everytime this delegate method is triggered you can trigger the corresponding navigation controller's popToRootViewController:animated method. Normally you'd have your app delegate be the tabbar controller delegate also, but that's up to your implementation.
Alternatively, I could use something like viewWillAppear, only switching tabs doesn't call viewWillAppear - IF I can access selectedItem or selectedIndex reliably from there.
The goal is to re-use a similar table view, with 3 tabs filling the table with differently filtered data.
I tried overriding didSelect and using the app delegate as UITabBarDelegate, but got the error 'Changing the delegate of a tab bar managed by a tab bar controller is not allowed.'
The tab bar controller, rootCt, is in the app delegate and works correctly.
So that's the trick I'm looking for - getting a notification from the root (tab bar) controller when the index has changed. Ideas?
Try implementing an UITabBarController delegate. It has a method similar to the didSelect: method offered by UITabBar delegate:
tabBarController:didSelectViewController:. It will be called after the user has selected another tab.
See: UITabBarControllerDelegate Protocol Reference
tabBarController.tabBar.selectedItem.tag
It will give you the tag of current selected tabbar index
If you are using tabBar den
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
is the delegate method that gets called when tabbar is selected.
happy iCoding...
You can use the delegate method of UITabBarControllerDelegate
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
and in that you have self.selectedIndex will give you the selected index.
I don't usually do this kind of thing (answer my own question). But here goes.
For example, if I click tab 2, then tab 3, then tab 2 again, viewWillAppear for that view is called, but the didSelectViewController method is not - and selectedIndex is not changed!
It appears as if selectedIndex is only updated if a view is loaded, not if the view is already loaded and simply appears.
I did some testing, and unlike selectedIndex, the tab bar's selectedItem is correctly updated (in viewWillAppear for the view in the clicked tab) even if the view is already loaded. By putting f.ex. the tabs' titles in an array, the matching index can be looked up.
So I will omit the didSelectViewController and won't need a UITabBarController, I only need to connect the UITabBar to an IBOutlet and use [myTabBar selectedItem].title to initialize correctly in the re-used view's viewWillAppear.
If someone offers a more generic/useful/simple solution I'll gladly mark that! Will check back in a few days and mark this if not. Just glad I made it work :)
I am using Tab bar + navigation based application and I have 4 tab bars. When I navigate from one view controller to another view controller, the viewWillAppear: method doesn't seem to respond and I am being forced to call it manually by creating the object of the next view controller. So my question is, how do I avoid calling the viewWillAppear: method manually whenever I navigate from one view controller to another? Instead, it should get triggered automatically just like the viewdidLoad: method gets triggered when you navigate from one view controller to other. Please guide me on how could I do that.
Hoping for the best possible Answer
Thanks in Advance
You are correct, viewWillAppear is a little special, it is usually called automatically but in some cases including when you are adding a view controllers view manually (view addSubview:), and also when adding this as a view controller to a UITabBarController or UINavigationCnotroller (of which you have both !) it doesn't get messaged.
This however is only for the root view, as you navigate (maybe with a navigation controller) back and forth, that root view's viewWillAppear will get triggered as some point.
In short, if you need to implement something in viewWillAppear in these cases, you should message it yourself when you know it's going to be presented. You can handle this case in your view controller, check out the following article about the matter:
http://www.touchthatfruit.com/viewwillappear-and-viewdidappear-not-being-ca
Good luck.
You should check UITabBarDelegate then look for the method:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item.
Description: Sent to the delegate when the user selects a tab bar
item.
In some apps that have a tab bar controller, each tab also needs a nav controller before a view can be added:
[[[_mainTabController topViewController] navigationController] pushViewController:renewalScreen animated:YES];
Do you mean 4 tab items on a tab bar, rather than '4 tab bars'? If you have a tab bar with tab items, the viewWillAppear: methods absolutely should be called by the system as the tabs are selected by the user. You could have other issues that are causing the problem.
You didn't forget to call [super viewWillAppear] somewhere?
Try using the viewDidAppear method instead.
Let's say I have a Tab Bar Controller with a tab A. A has a navigation controller, which lets me push new views onto the stack. Right now, if I tap A on the Tab Bar, all of the elements in A's stack will pop.
Is there a nice way to disable this? I have a sequence of views that are displayed with the navigation controller that takes user input would not like all of that to be lost with a slip of the finger.
Thanks in advance, and please let me know if my question is unclear.
Try setting up a delegate for your UITabBarController, and implement:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
If the same view controller is being selected, return NO. Then the navigation stack should not change.
Note it will only be called for the same tab you are already on from iOS 3.0 on, but at this point I would only target iOS 3.0+.
I have the next question:
In my project I have the next:
UItabbarController
....Some UINAvigationControllers....
*(1) UINavigationController
UIViewController (UItableView) - When select one row it goes to...(by push)
UIViewController (UItableView)
My problem is when i click in the tab bar item, I see the viewController view like last time that i saw this, and no reload to the *(1) first view another time.
Where I need to write sth for each time that i click in a tab bar item i reload the first view of this tab bar item.
Thanks!
If I understand your question correctly, you are trying to return the navigation controller to the root element when it's tab bar item is selected.
To do this, set some object (e.g. your application delegate, but it can be some other object instead) to be the delegate for your UITabBarController. (If you use the application delegate, it will be the delegate for more than one thing, which is fine.) Then, implement the tabBarController:didSelectViewController: method. In that method, tell the selected view controller (which should be a NavigationController) to return to the root view controller.
Something like this. Add this implementation to your AppDelegate.m class:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
[viewController popToRootViewControllerAnimated:NO];
}
In your .xib file, set the delegate for the TabBarController to the the AppDelegate. (If you are programmatically creating the tabBar, you'll have to do it programmatically there.)
As you suspected, trying to do this in viewWillAppear method, or anything other method, of the view controller that live in the navigation controller is not the correct approach. It is a method to perform on the navigation controller, and detected by the delegate of the tab bar.
Try putting your callback code to reload the view in the viewWillAppear or viewDidAppear methods. These are both called every time a view controller displays it's view on the screen.
Also feel free to copy and paste your actual code, it usually makes things easier on our end :)