Mam aplikację na iPhone'a, która używa a UINavigationController
do prezentowania interfejsu szczegółowego: najpierw jeden widok, potem drugi, aż do czterech poziomów głębokości. Chcę, aby pierwsze trzy widoki były ograniczone do orientacji pionowej i tylko ostatni widok powinien mieć możliwość obrócenia do poziomu. Wracając z czwartego widoku do trzeciego, a czwarty widok był w orientacji poziomej, chcę, aby wszystko wróciło do pionu.
W iOS 5 po prostu zdefiniowałem shouldAutorotateToInterfaceOrientation:
w każdym z moich kontrolerów widoku, aby zwracać TAK dla dopuszczalnych orientacji. Wszystko działało zgodnie z opisem powyżej, w tym powrót do portretu, nawet jeśli urządzenie było trzymane w orientacji poziomej podczas powrotu z kontrolera widoku # 4 do # 3.
W iOS 6 wszystkie kontrolery widoku obracają się do poziomu, łamiąc te, które nie były przeznaczone. W informacjach o wydaniu iOS 6 jest napisane
Większa odpowiedzialność przenosi się na aplikację i jej delegata. Teraz kontenery iOS (takie jak
UINavigationController
) nie konsultują się ze swoimi dziećmi w celu ustalenia, czy powinny one wykonywać autorotowanie. [...] System pyta najwyżej położony kontroler widoku pełnoekranowego (zwykle kontroler widoku głównego) o obsługiwane orientacje interfejsu za każdym razem, gdy urządzenie się obraca lub gdy kontroler widoku jest prezentowany w trybie prezentacji pełnoekranowej. Ponadto obsługiwane orientacje są pobierane tylko wtedy, gdy ten kontroler widoku zwraca wartość YES ze swojejshouldAutorotate
metody. [...] System określa, czy orientacja jest obsługiwana przez przecięcie wartości zwracanej przezsupportedInterfaceOrientationsForWindow:
metodę aplikacji z wartością zwracaną przezsupportedInterfaceOrientations
metodę najwyższego pełnoekranowego kontrolera.
Więc podklasowałem UINavigationController
, nadałem mojej MainNavigationController
właściwości boolowskiej landscapeOK
i użyłem tego do zwrócenia dopuszczalnych orientacji w supportedInterfaceOrientations
. Następnie w każdej z viewWillAppear:
metod kontrolerów widoku mam taką linię
[(MainNavigationController*)[self navigationController] setLandscapeOK:YES];
powiedzieć mojemu MainNavigationController
pożądanemu zachowaniu.
Pojawia się pytanie: jeśli teraz przejdę do mojego czwartego widoku w trybie portretowym i obrócę telefon, obróci się on do poziomu. Teraz naciskam przycisk Wstecz, aby wrócić do mojego trzeciego widoku, który powinien być tylko portretem. Ale nie obraca się z powrotem. Jak mam to zrobić?
próbowałem
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait]
w viewWillAppear
metodzie mojego trzeciego kontrolera widoku, ale nic nie robi. Czy to niewłaściwa metoda wywołania, czy może niewłaściwe miejsce, aby to wywołać, czy też powinienem zaimplementować całość w zupełnie inny sposób?
źródło
Dodaj CustomNavigationController
Zastąp w nim te metody:
Teraz dodaj wszystkie orientacje na liście
W kontrolerze widoku dodaj tylko te wymagane:
te metody zastępują metody kontrolera nawigacji
źródło
ViewController
w trybie portretowym, a mójViewController
jest w trybie krajobrazu i portretu. Daję również wsparcie zarówno w iOS 5.0, jak i iOS 6.0.Dlatego jestem zdezorientowany, ale to świetne rozwiązanie. dodaję CustomNavigationController do mojego głównego kontrolera widoku i udzielam wsparcia zgodnie z moimi potrzebami. Jeszcze raz dziękuję.Po przejrzeniu każdej odpowiedzi w niezliczonych podobnych pytaniach dotyczących SO, żadna z odpowiedzi nie działała dla mnie, ale dali mi kilka pomysłów. Oto, jak ostatecznie rozwiązałem problem:
Najpierw upewnij się, że Obsługiwane orientacje interfejsu w miejscu docelowym projektu zawierają wszystkie orientacje, które chcesz dla widoku obrotowego.
Następnie utwórz kategorię
UINavigationController
(ponieważ Apple mówi, aby nie tworzyć podklasy):Zaimportuj tę kategorię i kontroler widoku, który chcesz mieć możliwość obracania (który będę wywoływać
RotatingViewController
) do kontrolera widoku najwyższego poziomu, który powinien zawierać kontroler nawigacji. W tym widoku kontroler zaimplementujshouldAutorotate
w następujący sposób. Zwróć uwagę, że nie powinien to być ten sam kontroler widoku, który chcesz obrócić.Wreszcie w swoim
RotatingViewController
, zaimplementujshouldAutorotate
isupportedInterfaceOrientations
w następujący sposób:Powodem, dla którego musisz to zrobić, jest to, że iOS 6 daje kontrolę nad obrotem do głównego kontrolera widoku zamiast kontrolera widoku z góry. Jeśli chcesz, aby obrót pojedynczego widoku zachowywał się inaczej niż inne widoki w stosie, musisz napisać dla niego konkretny przypadek w głównym kontrolerze widoku.
źródło
Nie mam wystarczającej reputacji, aby skomentować odpowiedź @ Briana, więc dodam tutaj swoją notatkę.
Brian wspomniał, że iOS6 daje kontrolę rotacji do rootViewController - może to być nie tylko UINavigationController, jak wspomniano, ale także UITabBarController, którym był dla mnie. Moja struktura wygląda tak:
Dlatego dodałem metody najpierw w niestandardowym UITabBarController, następnie w niestandardowym UINavigationController, a na końcu w określonym UIViewController.
Przykład z UITabBarController i UINavigationController:
źródło
Chciałbym udzielić częściowej odpowiedzi na moje własne pytanie. Znalazłem następujący wiersz kodu, użyty w
viewWillAppear
metodzie mojej trzeciejUIViewController
, działa:Ale nie podoba mi się to rozwiązanie. Wykorzystuje sztuczkę, aby przypisać właściwość tylko do odczytu, która zgodnie z dokumentacją Apple reprezentuje fizyczną orientację urządzenia. To tak, jakby powiedzieć iPhone'owi, aby przeskoczył do właściwej orientacji w dłoni użytkownika.
Kusi mnie, aby zostawić to w mojej aplikacji, ponieważ po prostu działa. Ale nie wydaje się to właściwe, więc chciałbym pozostawić pytanie otwarte, aby uzyskać czyste rozwiązanie.
źródło
To jest, którego używam do obsługi orientacji w iOS 6.0
źródło
Ponieważ jest to bardzo popularny wątek. Pomyślałem, że dodam to, co uważam za najłatwiejszą odpowiedź. Działa to dla ios8 i nowszych
i
Otóż to. Cieszyć się!
Aha, i moje ViewControllery są osadzone w kontrolerze nawigacji, którego nie musiałem w żaden sposób tworzyć podklasy ani konfigurować.
źródło
To może nie działać dla wszystkich, ale dla mnie działa świetnie. Zamiast wdrażać ...
in viewWillAppear we wszystkich moich kontrolerach, postanowiłem scentralizować ten proces w mojej podklasie UINavigationController, zastępując metodę UINavigationControllerDelegate
navigationController:willShowViewController:animated:
Zauważyłem, że ta metoda delegata nie jest wywoływana podczas zdejmowania VC ze stosu nawigacyjnego. Nie stanowiło to dla mnie problemu, ponieważ obsługuję funkcję wsteczną z mojej podklasy UINavigationController, dzięki czemu mogę ustawić odpowiednie przyciski paska nawigacji i działania dla określonych VC, takich jak ten ...
Oto,
back
jak wygląda moja metoda, aby obsłużyć zdejmowanie VC ze stosu i ustawić odpowiednią preferencję rotacji ...Tak więc, jak widać, w zasadzie wszystko, co się dzieje, to najpierw ustawiam dwie właściwości ...
w
navigationController:willShowViewController:animated:
którym określi obsługiwane orientacje w ramach tego VC, który ma zostać przedstawiony. Podczas wyskakiwania VC wywoływana jest moja niestandardowa metoda „wstecz”, a następnie ustawiam isLcapesOK na to, co zostało zapisane za pomocą poprzedniej wartości VCLcapesOK.Jak powiedziałem, może to nie działać dla wszystkich, ale działa świetnie i nie muszę się martwić o dodanie kodu do każdego z moich kontrolerów widoku, udało mi się to wszystko scentralizować w podklasie UINavigationController.
Mam nadzieję, że to komuś pomoże, tak jak mnie. Dzięki, Jeremy.
źródło
Przejdź do pliku Info.plist i wprowadź zmianę
źródło
Chcesz wymusić portret aplikacji iOS 6 tylko wtedy możesz dodać poniższe metody do podklasy UIViewController
źródło
NSUInteger
generuje ostrzeżenie, mimo że jest to poprawny typ var. jeśli masz OCD, użyjUIInterfaceOrientationMask
zamiast tego.Chciałem, aby wszystkie moje VC były zablokowane w orientacji pionowej z wyjątkiem jednego. To mi się udało.
W głównym kontrolerze widoku wykryj rodzaj kontrolera widoku, który znajduje się w górnej części okna, i odpowiednio ustaw orientację aplikacji w metodzie supportedInterfaceOrientations . Na przykład potrzebowałem, aby moja aplikacja obracała się tylko wtedy, gdy widok sieciowy znajdował się na szczycie stosu. Oto, co dodałem w moim rootVC:
źródło
[[Utils getAppDelegate] appNavigationController]
. Narzędzia Myślę, że to jakaś klasa, którą masz, ale nie wiem, co w niej robisz. Każda pomoc byłaby świetna!Nie mam wystarczającej reputacji, aby odpowiedzieć na pytanie @Ram S pod odpowiedzią @micmdk, więc dodam tutaj swoją notatkę.
Kiedy używasz UITabbarController , spróbuj zmienić self.viewControllers.lastObject w kodzie @ micmdk na self.selectedViewController w następujący sposób:
źródło
Możesz implementować i przesłonić shouldAutorotate () i obsługiwaneInterfaceOrientations var we wszystkich klasach kontrolera widoku, które powinny być prezentowane w innych orientacjach niż te zdefiniowane w PLIŚCIE Twojej aplikacji.
Jednak w nietrywialnym interfejsie użytkownika możesz napotkać problem z dodaniem go do dziesiątek klas i nie chcesz, aby wszystkie były podklasą kilku wspólnych, które go obsługują (MyBaseTableViewController, MyBaseNavigationController i MyBaseTabBarController).
Ponieważ nie można zastąpić tej metody / var bezpośrednio w UIViewController, możesz to zrobić na jego podklasach, które są zwykle twoimi klasami podstawowymi, takimi jak UITableViewController, UINavigationController i UITabBarController.
Możesz więc zaimplementować kilka rozszerzeń i nadal skonfigurować MyPreciousViewController, aby wyświetlał się w innych orientacjach niż wszystkie inne, takie jak ten fragment kodu Swift 4:
źródło
Rozwiązałem ten sam problem.
Jeśli używasz do
UINavigationController
przekazywania kontrolerów widoku, musisz ustawić poniższe metody.W miejscu
LoginViewController
wykorzystania, któreUIViewController
chcesz pokazać. W moim przypadku chcę pokazaćLoginViewController
wPortrait
trybie innymViewControllers
wlandscape
trybie.źródło
Aby rozwiązać ten problem, użyj następującej metody
zwróć tylko wybraną orientację !!!
źródło