IPhone UINavigation Issue - вложенная анимация push может привести к повреждению навигационной панели

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

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];

Затем, если какая-то кнопка нажата в EventController, я вызываю:

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?

Ответ 1

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

Ответ 2

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

Ответ 3

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

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

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

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

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

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

В настоящее время документация яблок, таким образом, находится в файле executeSegueWithIdentifier: sender: reference:

Приложениям обычно не нужно запускать segues напрямую. Вместо этого вы настраиваете объект в Interface Builder, связанный с контроллером представления, например, элемент управления, встроенный в свою иерархию представлений, для запуска segue. Тем не менее, вы можете вызвать этот метод, чтобы вызвать segue программно, возможно, в ответ на некоторые действия, которые не могут быть указаны в файле ресурсов раскадровки. Например, вы можете вызвать его из специального обработчика действий, используемого для обработки событий встряхивания или акселерометра.

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

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

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

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

Ответ 4

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

приветствий.

Ответ 5

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

Ответ 6

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

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

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

Ответ 7

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

Ответ 8

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

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

Ответ 9

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

Ответ 10

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

Это было вызвано для меня, нажав 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];) проблема исчезла.

В основном урок заключается в том, что вы не должны изменять стек navigationController, если клавиатура отсутствует.

Ответ 11

Недавно я столкнулся с той же проблемой. Причина в том, что: - Я пытался ошибочно попытаться настроить контроллер просмотра. вы можете проверить этот сбой, установив точки останова на контроллерах push и pop View

Ответ 12

1) Возможно, вы могли бы попробовать передать необходимые переменные в качестве свойств, прежде чем нажимать UIViewController, а не использовать методы init с параметрами. Скорее всего, вам понадобятся эти параметры за пределами метода init.

Кроме того, в вашем методе initWithCoordinates: отсутствуют параметры. Возможно, ваши пользовательские методы init являются частью проблемы.

2) Только потому, что вы упомянули viewDidLoad - этот метод предназначен для инициализации после загрузки представления. Если вы создаете UIViewController в коде, как вам кажется, вы должны использовать loadView для настройки ваших подзонов.

Ответ 13

Мое решение было

[self performSelector: @selector (moveTo) withObject: nil afterDelay: 0,5];

Ответ 14

Это происходило для меня из-за моего UIControlEvents

    [button addTarget:self action:@selector(callSecondView) forControlEvents:UIControlEventAllTouchEvents];

Мне пришлось изменить UIControlEventAllTouchEvents на UIControlEventTouchUpInside или, тем не менее, вы хотите, чтобы ваша кнопка работала, если у вас возникла проблема из-за вызова UIButton.

Ответ 15

Не знаю о других. Я думаю, что большинство людей, использующих StoryBoard, сталкиваются с такой проблемой. Я использую XIB.

В моем случае Проблема была, когда я двигался в другое представление, используя push, Я также использовал

 [self.navigationController popViewControllerAnimated:YES];

в ViewWillDisappear текущего представления одновременно. Просто удалите его, и он отлично работает.

Я использовал POP из-за требования и потока. Иерархия была 1 → 2 → 3

Я был на виду 2 и хотел перейти к просмотру 3. В этом случае я столкнулся с этой ошибкой.

Ответ 16

В моем случае я оба настраивал push-сегу из раскадровки и программно. Надеюсь, что это поможет кому-то

Ответ 17

У меня тоже было это сообщение об ошибке, и переходы навигационной панели и навигационного контроллера были странными. Моя настройка была кучей контроллеров навигации, встроенных в контроллер панели вкладок. Проблема заключалась в том, что я не вызывал super.viewDidLoad() в моей реализации Controlbar-панели Tab viewDidLoad.

Вызов супер - это то, что документы четко указывают на то, что вы должны делать, переопределяя viewDidLoad, и я это усложнил.

Возможно, это тоже поможет кому-то другому!

Ответ 18

Я знаю, что на это был дан ответ, но он может помочь другим.

У меня была та же проблема, но это было вызвано тем, что я использовал плохое событие для информационной кнопки.  Я использовал "UIControlEventAllTouchEvents", и это сгенерировало два нажатия одного и того же представления в навигационном контроллере. Правильным событием было "UIControlEventTouchUpInside". Я новичок в iOS.

Ответ 19

Это решает проблему: https://github.com/nexuspod/SafeTransition

Если вы нажмете (или поп) контроллер представления с анимацией (анимированный: YES), он не будет завершен сразу, а плохие вещи произойдут, если вы сделаете еще один push или pop перед завершением анимации.

Чтобы воспроизвести эту ошибку, попробуйте одновременно нажать или вывести два контроллера представления. Пример:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    UIViewController *vc = [[UIViewController alloc] init];
    [self.navigationController pushViewController:vc animated:YES];
}

Вы получите эту ошибку:

2014-07-03 11: 54: 25.051 Демо [2840: 60b] вложенная анимация push привести к повреждению навигационной панели 2014-07-03 11: 54: 25.406 Демо [2840: 60b] Завершение перехода навигации в неожиданный государство. Дерево видимости панели навигации может быть повреждено.

Просто добавьте файлы кода в свой проект и сделайте ваш контроллер навигации в качестве подкласса APBaseNavigationController, и вам будет хорошо делать.

Ответ 20

Просто, чтобы завершить список, вот еще одна причина, которая может привести к тому, что "вложенная анимация push может привести к поврежденной панели навигации":

Я установил несколько NavigationController в TabBarController и установил selectedIndex в раскрывающемся списке Identifiy Properties. После перемещения активной вкладки Ошибка кода исчезла.