iPhone UINavigation Issue - вложенная push-анимация может привести к повреждению панели навигации - PullRequest
69 голосов
/ 03 апреля 2011

Я получаю следующие ошибки:

2011-04-02 14:55:23.350 AppName[42430:207] nested push animation can result in corrupted navigation bar
2011-04-02 14:55:23.352 AppName[42430:207] nested push animation can result in corrupted navigation bar
2011-04-02 14:55:23.729 AppName[42430:207] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
2011-04-02 14:55:23.729 AppName[42430:207] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.

Вот что я делаю. При нажатии определенной кнопки из контроллера представления я вызываю следующее:

EventsViewController *viewController = [[EventsViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
navController.navigationBar.tintColor = [UIColor blackColor];
[self presentModalViewController:navController animated:YES];
[viewController release];
[navController release];

Затем, если в EventsController нажать определенную кнопку, я вызываю:

SingleEventViewController *viewController = [[SingleEventViewController alloc] initWithEvent:[currentEvents objectAtIndex:indexPath.row]];
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];

Затем, если в SingleEventViewController нажать определенную кнопку, я вызываю:

EventMapView* viewController = [[EventMapView alloc] initWithCoordinates];
[[self navigationController] pushViewController:viewController animated:YES];
[viewController release];

Так, да, очевидно, что есть вложенные анимации push, но разве это не правильный путь? Я проверил код Apple DrillDownSave, и похоже, именно так они и делают. Имеет ли значение, что я использую методы init вместо методов viewDidLoad?

Ответы [ 20 ]

118 голосов
/ 13 июля 2011

Вызов pushViewController до viewDidAppear небезопасен.

93 голосов
/ 19 января 2013

АВАРИЙНО ТРИГГЕРИРУЕТ ОДИН И ТОТ ЖЕ СЕМЬ ДВАЖДЫ Один раз в коде и один раз из конструктора интерфейса, но оба одновременно ...

Я получаюта же ошибка, что и у вас.Единственная моя проблема заключалась в том, что я случайно запускал одну и ту же передачу дважды.Один раз из конструктора интерфейса и один раз из моего кода.

У меня есть UITableView.Когда ячейка выбрана, возникает ошибка в построителе интерфейса.Вот моя проблема, я настроил segu для непосредственного запуска, щелкнув CELL ITSELf, внутри конструктора интерфейса, а затем в моем коде, который я имел под didSelectRowAtIndexPath, код, который будет запускать ту же самую передачу ... вот так ...

[self performSegueWithIdentifier:@"MySegue" sender:tableView];

Это означает, что когда didSelectRowAtIndexPath вызывается из-за того, что строка была выбрана, она запускает переход с указанной строкой кода.Затем конструктор интерфейса также запускает переход, потому что он напрямую связан с объектом ячейки в конструкторе интерфейса.Чтобы не допустить непосредственного запуска конструктора интерфейса.Вы должны подключить переход сверху контроллера вида, а не вкладываться внутрь, выходя из самой ячейки.

Так что если у вас возникла эта проблема по той же причине, что и у меня, то есть вывызывая один и тот же segue дважды, вы можете исправить это, отсоединив соединение от CELL DIRECTLY от вашего segue, и установив соединение segue, которое происходит в верхней части иерархии таблиц в IB, а не во вложенной ячейке.Подключите переход от самого View Controller к переходу.Если вы сделали это правильно, то при выборе перехода следует выделить ВЕСЬ вид, из которого он исходит, а не только ячейку.

Теперь документация Apples, таким образом, находится под executeSegueWithIdentifier: sender: reference:

Обычно приложениям не нужно запускать сегменты напрямую.Вместо этого вы настраиваете объект в Интерфейсном Разработчике, связанный с контроллером представления, такой как элемент управления, встроенный в его иерархию представления, для запуска перехода.Однако вы можете вызвать этот метод, чтобы программно инициировать переход, возможно, в ответ на какое-то действие, которое нельзя указать в файле ресурсов раскадровки.Например, вы можете вызвать его из обработчика настраиваемых действий, используемого для обработки событий встряхивания или акселерометра.

В моем случае у меня есть кнопка поиска для моего UITableView, и вызывается ли segue, когда таблица результатов поискаприсутствует, или присутствует нормальное табличное представление, должен быть определен.Поэтому мне нужно было напрямую запустить переход.

Итак, удалите встроенный элемент управления из компоновщика интерфейса и просто прикрепите его к самому контроллеру представления, а затем запустите переход в своем коде!

Теперь,нет больше двойных сегментов!И больше никаких ошибок.

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

12 голосов
/ 11 апреля 2011

У меня было то же сообщение о проблеме / ошибке, что и вы, только что, я искал решение и оказался в этом потоке, однако для себя я обнаружил, что в действительности решение имеет только один анимированный объект: ДА при выполнении вложенного толчок (я поставил анимацию: ДА только для последнего толчка), надеюсь, это поможет

веселит.

10 голосов
/ 09 апреля 2011

Я понял это.Очевидно, что если вы вызываете -pushViewController из-за -didSelectRowAtIndexPath метода UITableViewDelegate, он не работаетПеремещение вызова в эту функцию сработало.Weird.

8 голосов
/ 20 февраля 2012

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

4 голосов
/ 03 апреля 2011

Что вы имеете в виду, когда говорите, что используете методы init вместо методов viewDidLoad?

Если вы запускаете новый контроллер представления до того, как старый push имеет плохой шанс для действий, вы получите этовид ошибки.Таким образом, помещение определенного кода в init и преждевременное выполнение действий может привести к сообщению об ошибке.

В момент запуска init на контроллере представления представление еще не загружено!

2 голосов
/ 02 октября 2013

Хм, у меня была эта проблема, и я новичок во всей сцене разработки для iOS. Но после просмотра моего инспектора соединений (с владельцем файла) в конструкторе интерфейса я обнаружил, что, поскольку я скопировал кнопку, ей был назначен предыдущий метод кнопок, а также новый метод, который я создал. Я предполагаю, что именно отсюда и появился вложенный аспект моей проблемы, поскольку он выполнял 2 разных метода, оба из которых выдвигали представление на Nav Controller. Я знаю, что на этот вопрос уже был дан ответ, но я решил, что поднимет это на тот случай, если кто-нибудь еще совершит глупую ошибку, как моя.

1 голос
/ 17 июля 2012

На этот вопрос уже отвечали, но я подумал, что это может помочь другим, поскольку я получил ту же ошибку, но без использования табличных представлений.Я наконец-то понял проблему.

У меня была существующая кнопка, чье IBAction вызвало pushViewController.Я создал новую кнопку, скопировав существующую кнопку.Новая кнопка также имела действие, которое вызывало pushViewController.Когда новая кнопка была нажата (подправить внутри), и контроллер вида был нажат, я получил эту ошибку.Я удалил новую кнопку, создал ее с нуля, привязал ее к существующим выходам и действиям, и ошибка исчезла.

1 голос
/ 09 июня 2013

столкнулся с той же проблемой.В моем случае я пропустил перерыв в операторе switch, поэтому два перехода были запущены одновременноЛегко исправить для меня.

1 голос
/ 02 апреля 2014

Моя проблема связана с активностью клавиатуры.

Это вызвано тем, что я выдвинул ViewController из метода делегата textField:

-(void)textFieldDidBeginEditing:(UITextField *)textField{

        FilterLocationViewController *destViewController = (FilterLocationViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"FilterLocationViewController"];

        [self.navigationController pushViewController:destViewController animated:YES];

}

Изменив код на это:

-(void)textFieldDidBeginEditing:(UITextField *)textField{

        [_textFieldLocation resignFirstResponder]; //adding this line

        FilterLocationViewController *destViewController = (FilterLocationViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"FilterLocationViewController"];

        [self.navigationController pushViewController:destViewController animated:YES];

}

(добавив строку [textField resignFirstResponder];) проблема ушла.

По сути, урок заключается в том, что вам не следует изменять стек навигационного контроллера, если клавиатура отсутствует.

...