Просто начал использовать Xcode 4.5, и я получил эту ошибку в консоли:
Предупреждение. Попытайтесь представить <finishViewController: 0x1e56e0a0> в <ViewController: 0x1ec3e000>, чье представление не находится в иерархии окон!
Представление все еще отображается, и все в приложении работает нормально. Это что-то новое в iOS 6?
Это код, который я использую для переключения между представлениями:
UIStoryboard *storyboard = self.storyboard;
finishViewController *finished =
[storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];
[self presentViewController:finished animated:NO completion:NULL];
presentViewController:animated:completion
навигационный контроллер. Вы делаете это в приложении делегата?Ответы:
Откуда вы вызываете этот метод? У меня была проблема, когда я пытался представить модальный контроллер представления в
viewDidLoad
методе. Решением для меня было перенести этот вызов наviewDidAppear:
метод.Я предполагаю, что представление контроллера представления не находится в иерархии представления окна в тот момент, когда оно было загружено (когда
viewDidLoad
сообщение отправлено), но оно находится в иерархии окна после того, как оно было представлено (когдаviewDidAppear:
сообщение отправлено) ,предосторожность
Если вы сделаете вызов в
presentViewController:animated:completion:
in,viewDidAppear:
вы можете столкнуться с проблемой, из-за которой контроллер модального представления всегда отображается всякий раз, когда появляется представление контроллера представления (что имеет смысл!), И поэтому представляемый контроллер модального представления никогда не исчезнет. ,Возможно, это не лучшее место для представления контроллера модального вида, или, возможно, необходимо сохранить какое-то дополнительное состояние, которое позволяет контроллеру представления решить, должен ли он немедленно представить контроллер модального вида.
источник
Еще одна потенциальная причина:
У меня была эта проблема, когда я случайно представлял один и тот же контроллер представления дважды. (Один раз с помощью
performSegueWithIdentifer:sender:
которого вызывался при нажатии кнопки, второй - с переходом, подключенным непосредственно к кнопке).По сути, два segues были запущены одновременно, и я получил ошибку:
Attempt to present X on Y whose view is not in the window hierarchy!
источник
present(viewController, animated: true, completion: nil)
внутри цикла.viewWillLayoutSubviews
иviewDidLayoutSubviews
(iOS 5.0+) может использоваться для этой цели. Они вызываются раньше, чем viewDidAppear.источник
Для отображения любого подпредставления на основной вид, пожалуйста, используйте следующий код
Для отклонения любого подпредставления от основного вида, пожалуйста, используйте следующий код
источник
Я также столкнулся с этой проблемой, когда я пытался представить
UIViewController
вviewDidLoad
. Ответ Джеймса Бедфорда сработал, но мое приложение сначала показывало фон в течение 1 или 2 секунд.После некоторых исследований я нашел способ решить эту проблему с помощью
addChildViewController
.источник
Возможно, как и у меня, у вас неправильный рут
viewController
Я хочу отобразить
ViewController
вnon-UIViewController
контексте,Поэтому я не могу использовать такой код:
Итак, я получаю UIViewController:
По какой-то причине (логическая ошибка),
rootViewController
это нечто иное, чем ожидалось (нормальныйUIViewController
). Затем я исправляю ошибку, заменяяrootViewController
ееUINavigationController
, и проблема исчезла.источник
TL; DR Вы можете иметь только 1 rootViewController и его последний представленный. Так что не пытайтесь, чтобы viewcontroller представлял другой viewcontroller, когда он уже представлен тот, который не был отклонен.
После некоторого собственного тестирования я пришел к выводу.
Если у вас есть rootViewController, который вы хотите представить все, вы можете столкнуться с этой проблемой.
Вот мой код rootController (open - мой ярлык для представления viewcontroller из корня).
Если я вызываю open два раза подряд (независимо от прошедшего времени), это будет прекрасно работать при первом открытии, но НЕ при втором открытии. Вторая попытка открытия приведет к ошибке выше.
Однако, если я закрываю последний представленный вид, затем вызываю open, он прекрасно работает, когда я снова вызываю open (на другом viewcontroller).
Я пришел к выводу, что rootViewController только MOST-RECENT-CALL находится в иерархии представления (даже если вы не отклонили его или не удалили представление). Я попытался поиграть со всеми вызовами загрузчика (viewDidLoad, viewDidAppear и выполнить отложенные вызовы диспетчеризации) и обнаружил, что единственный способ заставить его работать - это ТОЛЬКО вызов подарка с самого верхнего контроллера представления.
источник
wait
wait
decide
push screen to front
и это невозможно, это IOS ????Мой вопрос я выполнял SEGUE в
UIApplicationDelegate
«SdidFinishLaunchingWithOptions
метода , прежде чем я позвонилmakeKeyAndVisible()
в окне.источник
В моей ситуации я не смог переопределить класс. Итак, вот что я получил:
источник
У меня такая же проблема. Мне пришлось встроить контроллер навигации и представить контроллер через него. Ниже приведен пример кода.
источник
Если у вас есть объект AVPlayer с воспроизводимым видео, сначала нужно приостановить видео.
источник
Я была такая же проблема. Проблема была в том, что executeSegueWithIdentifier был вызван уведомлением, как только я поместил уведомление в основной поток, предупреждающее сообщение исчезло.
источник
Это работает нормально, попробуйте это. Ссылка на сайт
источник
В случае, если это кому-нибудь поможет, моя проблема была чрезвычайно глупой. Совершенно моя вина, конечно. Уведомление инициировало метод, который вызывал модальное. Но я не удалял уведомление правильно, поэтому в какой-то момент у меня было бы больше одного уведомления, чтобы модал вызывался несколько раз. Конечно, после того, как вы вызываете модальное устройство один раз, контроллер представления, который вызывает его, больше не находится в иерархии представления, поэтому мы видим эту проблему. Моя ситуация также вызвала массу других проблем, как и следовало ожидать.
Подводя итог, что бы вы ни делали, убедитесь, что модал вызывается не более одного раза .
источник
Я получил такой код, который наконец-то работает для меня (Swift), учитывая, что вы хотите отображать его
viewController
практически из любого места. Этот код, очевидно, вылетает, когда нет доступного rootViewController, это открытый конец. Он также не включает обычно требуемый переход на поток пользовательского интерфейса, используяисточник
Такое предупреждение может означать, что Вы пытаетесь представить новое
View Controller
через, вNavigation Controller
то время как этоNavigation Controller
в настоящее время представляет другоеView Controller
. Чтобы это исправить, вы должныView Controller
сначала отменить представленный в настоящее время, а по завершении представить новый. Другой причиной предупреждения может быть попытка представитьView Controller
в потоке другой, чемmain
.источник
У меня была похожая проблема на Swift 4.2, но мое представление не было представлено из цикла просмотра. Я обнаружил, что у меня была множественная передача, которая должна быть представлена одновременно. Поэтому я использовал dispatchAsyncAfter.
источник
Я исправил это, переместив
start()
функцию вdismiss
блок завершения:Start содержит два вызова:
self.present()
один для UINavigationController и другой для aUIImagePickerController
.Это исправило это для меня.
источник
Вы также можете получить это предупреждение при выполнении перехода от контроллера представления, встроенного в контейнер. Правильное решение - использовать segue от родителя контейнера, а не от контроллера представления контейнера.
источник
Должен написать ниже строки.
вместо
в UIViewController
источник
С Swift 3 ...
Другой возможной причиной этого, которая случилась со мной, был переход от tableViewCell к другому ViewController на раскадровке. Я также использовал,
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {}
когда ячейка была нажата.Я исправил эту проблему, перейдя от ViewController к ViewController.
источник
У меня была эта проблема, и основной причиной была подписка на обработчик нажатия кнопки (TouchUpInside) несколько раз.
Он подписывался в ViewWillAppear, который вызывался несколько раз, так как мы добавили навигацию, чтобы перейти к другому контроллеру, а затем вернуться к нему.
источник
Со мной случилось, что переход в раскадровке был каким-то сломан . Удаление перехода (и создание того же самого перехода снова) решило проблему.
источник
С вашим главным окном, скорее всего, будут времена с переходами, которые несовместимы с представлением оповещения. Чтобы в любой момент жизненного цикла приложения можно было отправлять оповещения, у вас должно быть отдельное окно для выполнения работы.
Основное использование, которое по замыслу всегда будет успешным:
источник
К сожалению, принятое решение не сработало для моего случая. Я пытался перейти к новому View Controller сразу после перемотки с другого View Controller.
Я нашел решение, используя флаг, чтобы указать, какой раскрутке был вызван segue.
Затем представьте желаемый ВК с
present(_ viewControllerToPresent: UIViewController)
По сути, приведенный выше код позволит мне перехватить раскрутку с помощью Login / SignUp VC и перейти к панели инструментов, или перехватить действие раскрутки с помощью пароля VC Забыли пароль и перейти на страницу входа.
источник
Я исправил эту ошибку, сохранив самый верхний viewcontroller в константу, которая находится в цикле while по rootViewController:
источник
Я обнаружил, что эта ошибка появилась после обновления XCode, я верю в Swift 5 . Проблема возникла, когда я программно запустил переход непосредственно после размотки контроллера представления.
Решение пришло, исправляя связанную ошибку, которая заключается в том, что теперь пользователь мог раскручивать сегменты, проводя вниз по странице. Это нарушило логику моей программы.
Это было исправлено путем изменения режима презентации на всех контроллерах представления с автоматического на полный экран .
Вы можете сделать это на панели атрибутов в конструкторе интерфейсов. Или посмотрите этот ответ, чтобы узнать, как это сделать программно.
источник
У меня тоже была эта проблема, но она не имела никакого отношения к срокам. Я использовал синглтон для обработки сцен и установил его в качестве ведущего. Другими словами, «Я» не было связано ни с чем. Я просто сделал свою внутреннюю "сцену" новым ведущим и вуаля, это сработало. (Вуаля теряет связь после того, как вы узнаете его значение, хе).
Так что да, речь идет не о «волшебном поиске правильного пути», а о понимании того, где находится ваш код и что он делает. Я рад, что Apple дала такое простое английское предупреждение, даже с эмоциями. Престижность яблочному разработчику, который сделал это !!
источник
Если по каким-либо причинам другие решения не выглядят хорошими, вы все равно можете использовать этот старый добрый способ
workaround
представления с задержкой 0, например так:Хотя я не видел никакой документированной гарантии того, что ваш VC будет находиться в иерархии представлений в запланированном к исполнению блоке диспетчеризации, я заметил, что он будет работать нормально.
Использование задержки, например, 0,2 с, также возможно. И самое лучшее - таким образом вам не нужно связываться с логической переменной в
viewDidAppear:
источник
Это работает для представления любого контроллера представления, если у вас есть доступный контроллер навигации. self.navigationController? .present (MyViewController, animated: true, завершение: nil) Кроме того, я также могу представить оповещения и почтовый контроллер.
источник