Objective-C:如何为 TabBarController 正确设置 didSelectViewController 方法,以便每次点击时我都可以刷新 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 并且相应的方法不再起作用

The issue without break

The issue with break

问题

如何正确设置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];
    }

}

我的故事板

因此 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

第二视图控制器

#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

如果我 运行 开始 select 进入 FirstViewController 的选项卡,然后 select 进入 SecondViewController 的选项卡,然后返回 select 进入 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-less-than-30-seconds-ef884520f0df 如果你确实需要标签栏委托在每个视图控制器上做某事 selection,我建议有一个中心对象,它是唯一的标签栏委托并让它处理根据通过委托方法传入的视图控制器执行哪些任务 tabBarController:didSelectViewController: 作为另一个示例。