Objective-C: Как правильно установить метод didSelectViewController для TabBarController, чтобы я мог обновлять VC каждый раз, когда он касается - PullRequest
0 голосов
/ 12 сентября 2018

Пытается выполнить

Нажмите на tabbaritem, и он вызовет соответствующий метод на tabbaritem VC.

Выпуск

Когда я нажимаю tabbaritem2, он вызывает didSelectViewController на tabbaritem2, а затем соответствующий метод. Затем, когда я нажму tabbaritem3, он все равно вызовет didSelectViewController на tabbaritem3 и соответствующий метод.

Но когда я переключаюсь назад и нажимаю tabbaritem2. Он по-прежнему будет вызывать didSelectViewController для tabbaritem3, а не didSelectViewController для tabbaritem2, и соответствующий метод больше не работает

выпуск без перерыва

Проблема с перерывом

Вопрос

Как правильно настроить метод 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

1

1 Ответ

0 голосов
/ 12 сентября 2018

Таким образом, TabBarController может иметь только одного делегата за раз. В опубликованном вами коде вы устанавливаете tabBarController.delegate = self в каждом соответствующем методе жизненного цикла контроллеров viewDidLoad (вызывается один раз при первой загрузке представления). Таким образом, независимо от того, что будет загружен последний контроллер представления, будет заключительной 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 соответствующих контроллеров представления, а затем сохранить его), а затем использовать элемент управления pull для обновления, который позволяет пользователям обновлять данные по команде: https://medium.com/ios-os-x-development/ios-tips-pull-to-refresh-in-less-than-30-seconds-ef884520f0df Если вам определенно требуется, чтобы делегат панели вкладок что-то делал при каждом выборе контроллера представления, я бы порекомендовал иметь один центральный объект, который является единственным делегатом панели вкладок, и он обрабатывал, какие задачи выполнять на основе переданного контроллера представления. через метод делегата tabBarController:didSelectViewController: в качестве одного дополнительного примера.

...