Objective-C:如何正确设置 TabBarController 的 didSelectViewController 方法,这样我每次点击时都可以刷新 VC

Posted

技术标签:

【中文标题】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 【发布时间】:2018-09-12 10:53:11 【问题描述】:

努力完成

点击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];
    //
    //=================================================================================

类.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];
    


健身房.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];
    


我的故事板

【问题讨论】:

【参考方案1】:

所以 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

如果我运行它并首先选择 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 中,然后存储它),然后有一个拉动刷新控件,允许用户根据命令刷新数据:@987654321 @ 如果您确实需要选项卡栏委托在每个视图控制器选择上执行某些操作,我建议使用一个中心对象,它是唯一的选项卡栏委托,并让它根据通过传入的视图控制器处理要执行的任务委托方法tabBarController:didSelectViewController: 作为另一个示例。

【讨论】:

我是个菜鸟,你有什么其他模式或流程的推荐吗? 编辑了我的答案以包含一些附加信息。

以上是关于Objective-C:如何正确设置 TabBarController 的 didSelectViewController 方法,这样我每次点击时都可以刷新 VC的主要内容,如果未能解决你的问题,请参考以下文章

如何在 jqueryMobile 中正确创建类似于 iOS tabbarController 的 tabbar 控制器?

如何向TabBar添加ColorTween动画?

如何在 Sencha Touch tabBar 中使用附加图标?

Objective-C:如何正确处理 iOS 推送通知?

微信小程序如何设置自定义tabBar

iOS tabbar横线颜色及tabbar背景色设置,tabbar字体颜色 大小设置