«Приложение пыталось модально представить активный контроллер»?

101

Я только что обнаружил сбой NSInvalidArgumentExceptionс этим сообщением в приложении, которое раньше этого не делало.

Приложение попыталось модально представить активный контроллер UITabBarController: 0x83d7f00.

У меня есть объект, UITabBarControllerкоторый я создаю в, AppDelegateи передаю ему массив UIViewControllers.

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

- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController

Если этот контроллер представления относится к классу того, который я хочу представить модально, я возвращаю NO и делаю

[tabBarController presentModalViewController:viewController animated:YES];

И теперь я получаю эту ошибку, которая, кажется, означает, что вы не можете модально представить контроллер представления, который активен где-то еще (на панели вкладок ...). Я должен сказать, что я использую XCode 4.2 Developer Preview 7, поэтому это iOS 5 (я знаю о соглашении о неразглашении информации, но думаю, что не буду приводить никаких запрещенных подробностей). В настоящее время у меня нет установки XCode, чтобы проверить, вызывает ли сбой компиляция iOS4 SDK, но я почти полностью уверен, что это не так.

Я только хотел спросить, сталкивался ли кто-нибудь с этой проблемой или есть какие-либо предложения

Хавьер Сото
источник
До iOS 5 это не вызывало исключения, но ничего не возвращало. Начиная с iOS 5, эта команда вызывает исключение.
Frédéric Adda

Ответы:

104

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

UIViewController* vc1 = [[UIViewController alloc] init];
UIViewController* vc2 = [[UIViewController alloc] init];
UIViewController* vc3 = [[UIViewController alloc] init];

Вы добавили их на панель вкладок следующим образом:

UITabBarController* tabBarController = [[UITabBarController alloc] init];
[tabBarController setViewControllers:[NSArray arrayWithObjects:vc1, vc2, vc3, nil]];

Теперь вы пытаетесь сделать что-то вроде этого:

[tabBarController presentModalViewController:vc3];

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

Apple ожидает, что вы будете относиться к их элементам пользовательского интерфейса определенным образом. Это, вероятно, похоронено где-то в Руководстве по человеческому интерфейсу как «не делайте этого, потому что мы не ожидаем, что вы когда-нибудь захотите это сделать».

lswank
источник
6
Дело в том, что до iOS 5 это не было проблемой, отсюда и мое беспокойство! Что я сделал, так это добавил фиктивный UIViewController на панель вкладок и модально представил фактический экземпляр подкласса контроллера представления.
Хавьер Сото,
1
@Iswank, теперь в iOS 6, чтобы "упростить", они устарели PresentModalViewController, вызывая всевозможные проблемы с вращением ... вам нужно использовать presentViewController: animated: Завершение и проверить, как ваше приложение обрабатывает изменения
почемуоз,
15

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

[self dismissModalViewControllerAnimated:YES];

Когда я пытаюсь сделать это без анимации, он работает отлично, поэтому проблема в том, что контроллер все еще жив. Думаю, что лучшее решение - использовать dismissViewControllerAnimated:completion:для iOS5

Данил
источник
Это не сработает, если вы отклоните его с анимацией, потому что к тому времени, когда вы снова захотите представить контроллер модального представления, он все еще будет модально на экране, будучи анимированным.
Паскаль
2
В IOS 6.0 он отсутствует
Сумит Кумар Саха
12

В моем случае я пытался представить viewController (у меня есть ссылка на viewController в TabBarViewController) из разных контроллеров представления, и он давал сбой с указанным выше сообщением. В этом случае, чтобы избежать презентации, вы можете использовать

viewController.isBeingPresent

!viewController.isBeingPresented {
          // Present your ViewController only if its not present to the user currently.
}

Может кому-нибудь помочь.

Картик Рамеш
источник
он работает только в viewWillappperar, но когда я проверяю его перед представлением viewController, который уже представлен, он всегда возвращает false.
guru
1
У меня не работает. По-прежнему происходит сбой приложения. (! viewController.presentingViewController) проблема решена.
Argus
3

У меня была такая же проблема, я ее решаю. Вы можете попробовать этот код:

[tabBarController setSelectedIndex:1];
[self dismissModalViewControllerAnimated:YES];
Эрхан Демирчи
источник
3

Та же проблема возникла со мной, когда я попытался presentиспользовать дочерний контроллер представления вместо его UINavigationViewControllerродительского

Ник
источник
0

Просто удали

[tabBarController presentModalViewController:viewController animated:YES];

и хранить

[self dismissModalViewControllerAnimated:YES];
user170317
источник
это дает устаревшее предупреждение ... так что это альтернатива?
Kirtikumar A.
Здесь я использовал [blockSelf dismissViewControllerAnimated: YES Завершение: nil];
Kirtikumar A.
0

Вместо того, чтобы использовать:

self.present(viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Void)?)

ты можешь использовать:

self.navigationController?.pushViewController(viewController: UIViewController, animated: Bool)
Вимукти Раджапакша
источник
0

В моем случае я представлял rootViewControllerобъект, UINavigationControllerкогда я должен был представить его UINavigationController.

Лаура Корссак
источник