Использование setViewController из UINavigationController на iPhone не работает должным образом - PullRequest
3 голосов
/ 03 декабря 2010

У меня проблема с приложением iPhone, использующим UINavigationController. Когда я использую pushNavigationController, он работает нормально. IPhone выполняет анимацию при переключении на следующий ViewController. Но при использовании массива ViewControllers и метода setViewControllers в анимации возникает сбой, который может перерасти в явно видимую ошибку анимации.

Следующий фрагмент вызывается в корневом ViewController. В зависимости от условия он должен либо переключиться на ViewController1, либо напрямую перейти к ViewController2. В последнем случае пользователь может перейти обратно к vc1, затем к корню.

NSMutableArray* viewControllers = [NSMutableArray arrayWithCapacity:2];
// put us on the stack
[viewControllers addObject:self];
// add first VC
AuthentificationViewController* authentificationViewController =
  [[[AuthentificationViewController alloc] initWithNibName:@"AuthentificationViewController" bundle:nil] autorelease];
[viewControllers addObject:authentificationViewController];

if (someCondition == YES)
{
 UserAssignmentsListViewController* userAssignmentsListViewController =
      [[[UserAssignmentsListViewController alloc] initWithNibName:@"UserAssignmentsOverviewViewController" bundle:nil] autorelease];

 [viewControllers addObject:userAssignmentsListViewController];
}

[self.navigationController
  setViewControllers:[NSArray arrayWithArray:viewControllers] animated:YES];

Как вы можете видеть, я добавлю первый и, возможно, второй VC в массив, наконец, установив стек навигационного контроллера с анимацией. Это работает правильно, если я только добавлю первый контроллер. Но в случае, когда анимация должна идти на второй контроллер, заголовок панели навигации не будет «летать». Вместо этого есть пустой заголовок, пока анимация не закончится. И, что еще хуже, если я заменю заголовок панели навигации пользовательской кнопкой, эта кнопка будет отображаться в верхнем левом углу до завершения анимации. Это довольно показательная ошибка.

Я пытался использовать обходной путь с несколькими методами pushViewController, но анимация выглядит неправильно. Я хочу, чтобы навигация выполняла свою анимацию так же, как pushViewController. Единственная разница здесь в том, что я не добавляю VC, а устанавливаю весь стек сразу. Есть ли другой обходной путь здесь, или это можно рассматривать как ошибку фреймворка? Я думал об использовании только pushNavController для VC2, а затем каким-то образом вставить VC1 в стек, но это кажется невозможным.

Спасибо за все подсказки и советы. : -)

Технические данные: я использую iOS 4.2, компилирую для 4.0.

1 Ответ

5 голосов
/ 15 июня 2011

Наконец я нашел решение. Ошибка заключалась в том, что новый NavigationController верхнего уровня не был инициализирован и загружен должным образом, пока анимация не будет завершена. В моем случае UserAssignmentsListViewController имеет метод viewDidLoad, который не будет вызываться до тех пор, пока не будет выполнена анимация, но он устанавливает заголовок навигации (здесь: UIButton). Поэтому анимация не работает.

Решением является обращение к уже инициализированному контроллеру представления, когда дело доходит до помещения его в стек. Так что инициализируйте наш VC высшего уровня где-нибудь:

// initialize our top-level controller
ViewController* viewController2 = [[[ViewController alloc]
    initWithNibName:@"ViewController" bundle:nil] autorelease];

Затем, когда вы помещаете два или более VC в стек, первый уровень уже инициализируется, и анимация работает (следуя примеру из моего исходного вопроса):

NSMutableArray* viewControllers = [NSMutableArray arrayWithCapacity:2];
// put us on the stack, too
[viewControllers addObject:self];

ViewController* viewController1 = [[[ViewController alloc]
    initWithNibName:@"ViewController" bundle:nil] autorelease];
[viewControllers addObject:viewController1];

if (someCondition == YES)
{
    [viewControllers addObject:viewController2];
}

[self.navigationController
    setViewControllers:[NSArray arrayWithArray:viewControllers] animated:YES];
...