„Aplikacja próbowała zaprezentować modalnie aktywny kontroler”?


100

Właśnie natknąłem się na awarię NSInvalidArgumentExceptionz tym komunikatem w aplikacji, która wcześniej tego nie robiła.

Aplikacja próbowała przedstawić modalnie aktywny kontroler UITabBarController: 0x83d7f00.

Mam, UITabBarControllerktóry tworzę w AppDelegatei daję mu tablicę UIViewControllers.

Jeden z nich chcę zaprezentować modalnie po dotknięciu. Zrobiłem to, implementując metodę delegata

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

Jeśli ten kontroler widoku jest tej samej klasy, co ten, który chcę przedstawić modalnie, zwracam NIE i robię

[tabBarController presentModalViewController:viewController animated:YES];

A teraz otrzymuję ten błąd, co wydaje się oznaczać, że nie można modalnie zaprezentować kontrolera widoku, który jest aktywny gdzieś indziej (na pasku kart ...) Powinienem powiedzieć, że jestem na XCode 4.2 Developer Preview 7, więc to jest iOS 5 (wiem o NDA, ale myślę, że nie podaję żadnych zakazanych szczegółów). Obecnie nie mam instalacji XCode do przetestowania, czy to powoduje awarię kompilacji z SDK iOS4, ale jestem prawie całkowicie pewien, że tak się nie stanie.

Chciałem tylko zapytać, czy ktoś doświadczył tego problemu lub ma jakieś sugestie


Przed iOS 5 nie spowodowało to wyjątku, ale nic nie zwróciło. Począwszy od iOS 5, to polecenie wywołuje wyjątek.
Frédéric Adda

Odpowiedzi:


103

Załóżmy, że masz trzy kontrolery widoku utworzone w następujący sposób:

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

Dodałeś je do takiego paska kart:

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

Teraz próbujesz zrobić coś takiego:

[tabBarController presentModalViewController:vc3];

Spowoduje to błąd, ponieważ ten kontroler paska zakładek ma śmiertelny uścisk na kontrolerze widoku, który mu dałeś. Nie możesz dodać go do tablicy kontrolerów widoku na pasku kart lub nie możesz go przedstawić modalnie.

Apple oczekuje, że będziesz traktować ich elementy interfejsu użytkownika w określony sposób. Jest to prawdopodobnie zakopane w Wytycznych dotyczących interfejsu ludzkiego jako „nie rób tego, ponieważ nie oczekujemy, że kiedykolwiek będziesz chciał to zrobić”.


6
Rzecz w tym, że przed iOS 5 nie było żadnego problemu, stąd moje obawy! To, co zrobiłem, to dodanie fikcyjnego UIViewController do paska kart i zaprezentowanie modalnie rzeczywistej instancji podklasy kontrolera widoku.
Javier Soto,

1
@Iswank, teraz w iOS 6, aby uczynić rzeczy „łatwiejszymi”, wycofali presentModalViewController, powodując różnego rodzaju problemy z rotacją ... musisz użyć presentViewController: animated: complete i sprawdź, jak Twoja aplikacja obsługuje zmiany
dlaczegooz

15

Mam ten sam problem. Próbuję przedstawić kontroler widoku zaraz po zamknięciu.

[self dismissModalViewControllerAnimated:YES];

Kiedy próbuję to zrobić bez animacji, działa idealnie, więc problem polega na tym, że kontroler wciąż żyje. Myślę, że najlepszym rozwiązaniem jest użycie dismissViewControllerAnimated:completion:na iOS5


Nie powiedzie się, jeśli odrzucisz go jako animowany, ponieważ do czasu, gdy chcesz ponownie zaprezentować kontroler widoku modalnego, nadal jest on modalnie na ekranie i jest animowany.
Pascal

2
Jest pozbawiony w IOS 6.0
Sumit Kumar Saha

12

W moim przypadku próbowałem przedstawić ViewController (mam odniesienie do viewController w TabBarViewController) z różnych kontrolerów widoku i zawieszał się z powyższym komunikatem. W takim przypadku, aby uniknąć prezentacji, możesz użyć

viewController.isBeingPresented

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

Może komuś pomóc.


działa tylko w viewWillappperar, ale gdy mam to sprawdzić przed zaprezentowaniem viewController, który jest już przedstawiony, zawsze zwraca false.
guru

1
Nie działa dla mnie. Nadal występuje awaria aplikacji. (! viewController.presentingViewController) rozwiązany problem.
Argus

3

Miałem ten sam problem, rozwiązuję go. Możesz wypróbować ten kod:

[tabBarController setSelectedIndex:1];
[self dismissModalViewControllerAnimated:YES];

2

Ten sam problem wystąpił ze mną, gdy próbowałem presentużyć kontrolera widoku podrzędnego zamiast jego UINavigationViewControllerrodzica


0

Po prostu usuń

[tabBarController presentModalViewController:viewController animated:YES];

i zachowaj

[self dismissModalViewControllerAnimated:YES];

to daje przestarzałe ostrzeżenie ... więc co to jest alternativ?
Kirtikumar A.,

Tutaj użyłem [blockSelf dismissViewControllerAnimated: YES ukończenie: nil];
Kirtikumar A.,

0

Zamiast używać:

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

możesz użyć:

self.navigationController?.pushViewController(viewController: UIViewController, animated: Bool)

0

W moim przypadku przedstawiałem rootViewControllerto, UINavigationControllerkiedy miałem przedstawić UINavigationControllersiebie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.