it-swarm.com.ru

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

Затем, если в 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?

69
joshholat

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

10
joshholat

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

118
S B

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

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

У меня есть 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 при наличии таблицы результатов поиска или при обычном представлении таблицы. Так что мне нужно было напрямую начать переход.

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

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

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

93
user1927446

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

веселит.

11
code007

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

8
TigerCoding

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

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

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

4
occulus

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

2
N1234

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

1
salilathalye

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

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

1
Vito Andolini

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

1
Baljeet Singh

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

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

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

1
stackOverFlew

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

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

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

0
Mundi

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

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

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

0
John Riselvato

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

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

0
Carlos B

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

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

0
Ponja

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

В моем случае проблема была, когда я перемещался в другой вид с помощью Push, Я также использовал 

 [self.navigationController popViewControllerAnimated:YES];

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

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

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

0
Jasmeet

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

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

Может быть, это может помочь кому-то еще!

0
empee

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

0
Kreutzer