Objective-C:如何为TabBarController正确设置didSelectViewController方法,以便每次点击VC时都可以刷新VC [英] Objective-C: How to properly set didSelectViewController method for TabBarController, so I can refresh the VC everytime it is tapped
问题描述
试图完成
在tabbaritem
上点击,它将调用tabbaritem VC
上的相应方法.
问题
当我点击tabbaritem2
时,它将调用tabbaritem2
上的didSelectViewController
,然后调用相应的方法.然后,当我点击tabbaritem3
时,它仍会调用tabbaritem3
上的didSelectViewController
及其相应的方法.
但是当我切换回并点击tabbaritem2
时.它仍然会调用tabbaritem3
上的didSelectViewController
而不是tabbaritem2
上的didSelectViewController
,并且相应的方法不再起作用
问题
如何正确设置didSelectViewController
方法,以便在点击tabbaritem
时分别调用并加载该方法?
代码
MyTabBarController.m(我需要在这里做点什么吗?)
- (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];
//}
//=================================================================================
}
Classes.m
- (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];
}
}
Gym.m
- (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];
}
}
MyStoryBoard
因此TabBarController一次只能有一个委托.在您发布的代码中,您要在viewDidLoad的每个各自的视图控制器生命周期方法中设置tabBarController.delegate = self(在第一次加载视图时调用一次).因此,无论要加载的最后一个视图控制器都是最终的tabBarControllerDelegate.
这是一个非常简单的示例,以说明我的意思:
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
如果我运行此程序并首先选择FirstViewController的选项卡,然后选择SecondViewController的选项卡,然后返回选择FirstViewController的选项卡,这是我得到的日志结果:
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
所以我的建议是使用另一种模式,该模式仅维护一个协调器来处理TabBarDelegation.
根据您对其他建议的评论进行编辑
iOS中一个相当标准的习惯用法是从服务器加载一次数据(通常是在各个视图控制器的viewDidLoad中,然后将其存储),然后具有刷新控件,该控件允许用户根据命令刷新数据: https: //medium.com/ios-os-x-development/ios-tips-pull-to-refresh-in-少于30秒-ef884520f0df 如果您确实需要标签栏委托来做某事对于每个视图控制器选择,我建议有一个中心对象,它是唯一的选项卡栏委托,并让它根据通过委托方法tabBarController:didSelectViewController:
传入的视图控制器来处理要执行的任务. >
Trying to accomplish
Tap on the tabbaritem
and it will called the respective method on the tabbaritem VC
.
Issue
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
Question
How to properly set up the didSelectViewController
method so that when tabbaritem
is tapped it will call and load the method respectively?
Code
MyTabBarController.m (Do I need to do something here?)
- (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];
//}
//=================================================================================
}
Classes.m
- (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];
}
}
Gym.m
- (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];
}
}
MyStoryBoard
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.
这篇关于Objective-C:如何为TabBarController正确设置didSelectViewController方法,以便每次点击VC时都可以刷新VC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!