TabBatController с viewControllers

В моем приложении на основе tabBarController у меня есть четыре вкладки — tabA, tabB, tabC и tabD. Пользователь сможет переключаться между вкладками.

Теперь к моему вопросу:
- tabA, tabB и tabD имеют одиночный viewController
- tabC имеет 3 viewController'а - vc1, vc2 и vc3

Я столкнулся с проблемой, когда приложение запоминает, в каком viewController пользователь был последним, и когда пользователь нажимает tabC, управление переходит к последнему контроллеру представления, в котором находился пользователь. Например, скажем, следующая последовательность:

  1. Пользователь нажимает tabA: отображается контроллер представления для tabA
  2. Пользователь нажимает tabD : отображается контроллер представления для tabD
  3. Пользователь нажимает tabC : отображается контроллер просмотра vc1. При нажатии на какое-либо действие пользователь попадает в vc3.
  4. Пользователь нажимает tabB : отображается контроллер представления для tabB
  5. Пользователь нажимает вкладку C : отображается vc3 — вместо этого я хочу показать vc1

Пока пробовал в vc1 табC следующее, но управление на vc1 вообще не приходит:

- (void) viewWillAppear:(BOOL)animated {
      [self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:0] animated:YES];
}

Как я могу сказать tabC всегда загружать vc1?

С уважением - заранее спасибо....
Сэм.


person Sam    schedule 18.09.2011    source источник


Ответы (2)


Ваш вызов vc1 из tabC, скорее всего, не вызывается - viewWillAppear: вызывается только тогда, когда представление появляется на дисплее.

Возможно, вы захотите взглянуть на эту функцию:

- (void)tabBarController:(UITabBarController *)tabBarController 
   didSelectViewController:(UIViewController *)viewController

(Ссылка на документацию Apple Developer)

и эта функция:

- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated

(Ссылка на документацию Apple Developer)

Если вы реализуете это в своем tabBarController делегате, вы можете действовать, когда пользователь выбирает tabC, т.е.:

- (void)tabBarController:(UITabBarController *)tabBarController 
   didSelectViewController:(UIViewController *)viewController
{
    if (viewController == \* tabC view controller */) {
        [tabCViewController.navigationController popToRootViewController:YES];
    }
}
person dvorak    schedule 18.09.2011
comment
Спасибо за ответ. Мне не повезло с предложением. Я сделал AppDelegate TabBarControllerDelegate. Функция обратного вызова вызывается, однако, используя следующий код, я не могу использовать popToRootViewController, используя if ([viewController.tabBarItem.title isEqualToString:@vc1]) { NSArray *tmp = [self.tabBarController.navigationController viewControllers]; [self.tabBarController.navigationController popToRootViewController:YES]; } Массив tmp показывает ноль viewController'ов! - person Sam; 18.09.2011
comment
Используете ли вы навигационный контроллер в вкладке 3? Если да, то прямо сейчас ваш код получает tabBarController navagationController. Это не то, что вам нужно — tabBarController.navigationController будет выше tabBarController в иерархии представлений. Попробуйте [viewController.navigationController popToRootViewController:YES]; вместо [self.tabBarController.navigationController popToRootViewController:YES]; - person dvorak; 18.09.2011
comment
Извините за боль, но я все еще расстроен. PopToRootViewController, похоже, не помогает мне. Меня интересует одна вещь: tabC — это навигационный контроллер. Он знает о трех используемых VC (а именно, vc1, vc2, vc3). Как AppDelegate узнает об этом, потому что это TabBarControllerDelegate? - person Sam; 18.09.2011
comment
Каждый из контроллеров представления vc1, vc2 и vc3 имеет свойство navigationController. Для данного экземпляра UIViewController это свойство устанавливается для контроллера навигации, в стеке которого есть это представление. Таким образом, AppDelegate получает вызов - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController, а viewController.navigationController должен иметь навигационный контроллер на вкладке 3 (поскольку viewController должен находиться в стеке этого навигационного контроллера). - person dvorak; 18.09.2011

@dvorak: Спасибо за ответ - и извините, что затягиваю....

Я знаю, что то, что я пишу, не является ответом, но хотел показать код, с которым я работаю.

Мне не повезло с предложением. Я сделал AppDelegate TabBarControllerDelegate. Функция обратного вызова вызывается, однако, используя следующий код, я не могу использовать popToRootViewController:

- (void)tabBarController:(UITabBarController *)tbController didSelectViewController:(UIViewController *)viewController {
       NSLog(@"ViewController is <%@>", viewController.tabBarItem.title);
       if ([viewController.tabBarItem.title isEqualToString:@"tabC"]) {
           NSArray *tmp = [viewController.navigationController.tabBarController viewControllers];
          [viewController.navigationController popToRootViewControllerAnimated:YES];
       }
}

Я собрал все ViewController'ы в переменную tmp в надежде увидеть 3 ViewController'а в массиве после посещения всех трех VC tabC. Из tabC->vc3 я нажимаю tabB, а затем нажимаю tabC для упражнения. Массив tmp не содержит элементов в отладчике.

person Sam    schedule 18.09.2011