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

问题描述 投票:1回答:1

Trying to accomplish

点击tabbaritem,它将在tabbaritem VC上调用相应的方法。

Issue

当我点击tabbaritem2时,它会在didSelectViewController上调用tabbaritem2,然后是相应的方法。然后,当我点击tabbaritem3it仍然会在didSelectViewController和相应的方法上调用tabbaritem3

但当我切换回来并点击tabbaritem2。它仍然会在didSelectViewController上调用tabbaritem3而不是didSelectViewController上的tabbaritem2,并且相应的方法不再起作用了

The issue without break

The issue with break

Question

如何正确设置didSelectViewController方法,以便在点击tabbaritem时它将分别调用和加载方法?

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

1

objective-c uitabbarcontroller uitabbar uitabbaritem
1个回答
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

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-less-than-30-seconds-ef884520f0df如果你肯定需要标签栏委托在每个视图控制器选择上执行某些操作,我建议让一个中心对象是唯一的标签栏委托,并让它根据通过委托方法tabBarController:didSelectViewController:传入的视图控制器处理要执行的任务另外的例子。

热门问题
推荐问题
最新问题