Reputation: 811
Tap on the tabbaritem
and it will called the respective method on the tabbaritem VC
.
When I tap on tabbaritem2
it will call didSelectViewController
on tabbaritem2
and then the respective method. Then when I tap on tabbaritem3
it will still call the didSelectViewController
on tabbaritem3
and the respective method.
But when I switch back and tap on tabbaritem2
. It will still call the didSelectViewController
on tabbaritem3
and not didSelectViewController
on tabbaritem2
and the respective method doesn't work anymore
How to properly set up the didSelectViewController
method so that when tabbaritem
is tapped it will call and load the method respectively?
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
NSLog(@"didSelectViewController... ");
// if ([viewController isKindOfClass:[UINavigationController class]]) {
// [(UINavigationController *)viewController popToRootViewControllerAnimated:NO];
// }
//=== I tried the following but it is not loading the method=====================
//if ([viewController isKindOfClass:[ClassNavigationController class]]) { // Here newViewController is the controller where the webview reload happens.
// [[[Classes alloc] init] reloadWebViewData]; // We create and instance for the new controller and call the delegate method where the reload works.
//}
//if (viewController == [tabBarController.viewControllers objectAtIndex:2]){
// [(UINavigationController *)viewController popToRootViewControllerAnimated:YES];
// [[[Classes alloc] init] LoadClasses];
//}else if (viewController == [tabBarController.viewControllers objectAtIndex:3]){
// [(UINavigationController *)viewController popToRootViewControllerAnimated:YES];
// [[[Gym alloc] init] handleRefreshGym:nil];
//}else{
//=== The following code will make viewWillAppear load on each tab bar item
//=== Without it, tapping on new tab bar item will not load viewWillAppear
// [(UINavigationController *)viewController popToRootViewControllerAnimated:NO];
//}
//=================================================================================
}
- (void)viewDidLoad {
[super viewDidLoad];
UITabBarController *tabBarController = (UITabBarController*)[UIApplication sharedApplication].keyWindow.rootViewController ;
[tabBarController setDelegate:self];
}
-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
NSLog(@" Classes Called ");
if (viewController == [tabBarController.viewControllers objectAtIndex:2])
{
[(UINavigationController *)viewController popToRootViewControllerAnimated:YES];
[self handleRefresh:nil];
}else{
[(UINavigationController *)viewController popToRootViewControllerAnimated:NO];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
UITabBarController *tabBarController1 = (UITabBarController*)[UIApplication sharedApplication].keyWindow.rootViewController ;
[tabBarController1 setDelegate:self];
}
-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
NSLog(@" Gym Called ");
if (viewController == [tabBarController.viewControllers objectAtIndex:3])
{
[(UINavigationController *)viewController popToRootViewControllerAnimated:YES];
[self handleRefreshGym:nil];
}else{
[(UINavigationController *)viewController popToRootViewControllerAnimated:NO];
}
}
Upvotes: 1
Views: 264
Reputation: 2595
So the TabBarController can only have one delegate at a time. In the code you posted you're setting the tabBarController.delegate = self in each respective view controllers lifecycle method of viewDidLoad (called once when the view is first loaded). So whatever the last view controller is to load will be the final tabBarControllerDelegate.
Here's a very simple example to show what I mean:
FirstViewController
#import "FirstViewController.h"
@interface FirstViewController () <UITabBarControllerDelegate>
@end
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tabBarController.delegate = self;
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"Who's my tab bar controller delegate = %@", self.tabBarController.delegate);
}
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
NSLog(@"Delegate called on %@", NSStringFromClass([self class]));
}
@end
SecondViewController
#import "SecondViewController.h"
@interface SecondViewController () <UITabBarControllerDelegate>
@end
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tabBarController.delegate = self;
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"Who's my tab bar controller delegate = %@", self.tabBarController.delegate);
}
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
NSLog(@"Delegate called on %@", NSStringFromClass([self class]));
}
@end
If I run this and start by selecting the FirstViewController's tab, then select the SecondViewController's tab, then go back to selecting the FirstViewController's tab this is the log result I get:
First Tab Selected:
Who's my tab bar controller delegate = <FirstViewController: 0x7ff9eb406970>
Delegate called on FirstViewController
Second Tab Selected:
Who's my tab bar controller delegate = <SecondViewController: 0x7fa33ac0a540>
Delegate called on FirstViewController (this is still FirstViewController here because the tab bar selection occurred prior to setting the SecondViewController to the tabBarControllerDelegate)
First Tab Selected:
Who's my tab bar controller delegate = <SecondViewController: 0x7fa33ac0a540>
Delegate called on SecondViewController
Second Tab Selected:
Who's my tab bar controller delegate = <SecondViewController: 0x7fa33ac0a540>
Delegate called on SecondViewController
...
and it continues on that the SecondViewController will remain the delegate
So my recommendation would be to use a different pattern that just maintains one coordinator to handle the TabBarDelegation.
Edit in response to your comment about other recommendations
A rather standard idiom in iOS is loading your data from the server once (usually in viewDidLoad of the respective view controllers then storing it), then having a pull to refresh control which allows users to refresh the data on command: https://medium.com/ios-os-x-development/ios-tips-pull-to-refresh-in-less-than-30-seconds-ef884520f0df If you definitely require the tab bar delegate to do something on each view controller selection, I'd recommend having one central object that is the only tab bar delegate and having it handle what tasks to do based on the view controller passed in through the delegate method tabBarController:didSelectViewController:
as one additional example.
Upvotes: 1