Przed iOS 8 używaliśmy poniższego kodu w połączeniu z metodami supportedInterfaceOrientations i shouldAutoRotate , aby wymusić orientację aplikacji na dowolną konkretną orientację. Użyłem poniższego fragmentu kodu, aby programowo obrócić aplikację do żądanej orientacji. Po pierwsze, zmieniam orientację paska stanu. A następnie samo przedstawienie i natychmiastowe odrzucenie widoku modalnego powoduje obrócenie widoku do żądanej orientacji.
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
UIViewController *c = [[UIViewController alloc]init];
[self presentViewController:vc animated:NO completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];
Ale to zawodzi w iOS 8. Ponadto widziałem kilka odpowiedzi w przepełnieniu stosu, gdzie ludzie sugerowali, że powinniśmy zawsze unikać tego podejścia od iOS 8.
Mówiąc dokładniej, moja aplikacja jest aplikacją uniwersalną. W sumie są trzy kontrolery.
Kontroler pierwszego widoku - powinien obsługiwać wszystkie orientacje na iPadzie i tylko portret (przycisk ekranu głównego w dół) na iPhonie.
Kontroler Second View - powinien obsługiwać tylko krajobraz we wszystkich warunkach
Kontroler Third View - powinien obsługiwać tylko krajobraz w każdych warunkach
Używamy kontrolera nawigacji do nawigacji po stronach. Z pierwszego kontrolera widoku, po kliknięciu przycisku, przesuwamy drugi na stos. Tak więc, gdy nadejdzie drugi kontroler widoku, niezależnie od orientacji urządzenia, aplikacja powinna zablokować się tylko w orientacji poziomej.
Poniżej znajduje się moje shouldAutorotate
i supportedInterfaceOrientations
metody w kontrolerze drugiego i trzeciego widoku.
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscapeRight;
}
-(BOOL)shouldAutorotate {
return NO;
}
Czy jest jakieś rozwiązanie dla tego lub lepszego sposobu blokowania kontrolera widoku w określonej orientacji dla iOS 8. Proszę o pomoc!
źródło
Odpowiedzi:
IOS 7–10:
Cel C:
Swift 3:
Po prostu wywołaj to
- viewDidAppear:
z przedstawionego kontrolera widoku.źródło
[UIView setAnimationsEnabled:NO];
wviewWillAppear
i[UIView setAnimationsEnabled:YES];
wviewDidAppear
, related: stackoverflow.com/a/6292506/88597[UINavigationController attemptRotationToDeviceOrientation];
Obrót orientacji jest nieco bardziej skomplikowany, jeśli znajdujesz się wewnątrz
UINavigationController
lubUITabBarController
. Problem polega na tym, że jeśli kontroler widoku jest osadzony w jednym z tych kontrolerów, nawigacja lub kontroler paska kart ma pierwszeństwo i podejmuje decyzje o autorotacji i obsługiwanych orientacjach.Używam następujących 2 rozszerzeń w UINavigationController i UITabBarController, aby kontrolery widoku, które są osadzone w jednym z tych kontrolerów, mogły podejmować decyzje.
Daj kontrolerom widoku moc!
Swift 2.3
Szybki 3
Teraz możesz nadpisać
supportedInterfaceOrientations
metodę lub możesz zastąpićshouldAutoRotate
w kontrolerze widoku, który chcesz zablokować, w przeciwnym razie możesz pominąć nadpisania w innych kontrolerach widoku, które chcesz odziedziczyć domyślne zachowanie orientacji określone w pliku plist aplikacjiWyłącz rotację
Zablokuj do określonej orientacji
Teoretycznie powinno to działać dla wszystkich złożonych hierarchii kontrolerów widoku, ale zauważyłem problem z UITabBarController. Z jakiegoś powodu chce użyć domyślnej wartości orientacji. Zobacz następujący post na blogu, jeśli chcesz dowiedzieć się, jak obejść niektóre problemy:
Zablokuj obrót ekranu
źródło
Oto, co zadziałało dla mnie:
https://developer.apple.com/library//ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/clm/UIViewController/attemptRotationToDeviceOrientation
Nazwij to w swojej metodzie viewDidAppear:.
źródło
Odkryłem, że jeśli jest to kontroler widoku prezentowanego, możesz go przesłonić
preferredInterfaceOrientationForPresentation
Szybki:
źródło
W ten sposób działa dla mnie w Swift 2 iOS 8.x:
PS (ta metoda nie wymaga nadpisywania funkcji orientacji, takich jak shouldautorotate na każdym viewController, tylko jedna metoda w AppDelegate)
Zaznacz „Wymaga pełnego ekranu” w ogólnych informacjach o projekcie.
Tak więc w AppDelegate.swift utwórz zmienną:
Więc umieść również tę funkcję:
Tak więc w każdej klasie w projekcie możesz ustawić tę zmienną w viewWillAppear:
Jeśli musisz dokonać wyboru na podstawie typu urządzenia, możesz to zrobić:
źródło
Po pierwsze - to zły pomysł, ogólnie rzecz biorąc, coś jest nie tak z architekturą Twojej aplikacji, ale
sh..t happens
jeśli tak, możesz spróbować zrobić coś takiego jak poniżej:Niż w
AppDelegate
A kiedy chcesz zmienić orientację, wykonaj następujące czynności:
Uwaga: czasami urządzenie może nie aktualizować się po takim połączeniu, więc może być konieczne wykonanie następujących czynności
To wszystko
źródło
Powinno to działać od iOS 6 i nowszych, ale przetestowałem to tylko na iOS 8. Podklasa
UINavigationController
i nadpisanie następujących metod:Lub zapytaj widoczny kontroler widoku
i zastosuj tam metody.
źródło
To jest opinia na temat komentarzy w odpowiedzi Sida Shaha , dotyczących wyłączania animacji za pomocą:
Kod:
źródło
Jeśli używasz navigationViewController, powinieneś utworzyć własną nadklasę dla tego i nadpisać:
spowoduje to wyłączenie rotacji w SecondViewController, ale jeśli wypchniesz SecondViewController, gdy urządzenie jest w orientacji pionowej, SecondViewController pojawi się w trybie pionowym.
Załóżmy, że używasz scenorysu. Musisz stworzyć ręczne przejście ( jak to zrobić ) w metodzie „onClick”:
To wymusi orientację poziomą, zanim twoja superklasa wyłączy funkcję automatycznego obracania.
źródło
Na
Xcode 8
metodach są konwertowane na właściwości, więc następujące działa zSwift
:źródło
portrait
trybie bez względu na orientację na iPadzie, zshouldAutorotate
powrotem do prawdy, osiągnąłem to.Wypróbowałem wiele rozwiązań, ale ten, który zadziałał, jest następujący:
Nie ma potrzeby edytowania
info.plist
w iOS 8 i 9.Możliwe orientacje z dokumentacji Apple :
źródło
Połączenie odpowiedzi Sids i Koreys zadziałało dla mnie.
Rozszerzenie kontrolera nawigacji:
Następnie wyłączanie obracania w pojedynczym widoku
I obracanie do odpowiedniej orientacji przed przejściem
źródło
Najlepsze rozwiązanie powyżej:
nie zadziałało dla mnie, gdy wywołałem go w viewDidAppear prezentowanego kontrolera widoku. Jednak zadziałało, gdy wywołałem go w preparatForSegue w kontrolerze widoku prezentacji.
(Przepraszamy, za mało punktów reputacji, aby skomentować to rozwiązanie, więc musiałem to dodać w ten sposób)
źródło
[iOS9 +] Jeśli ktoś przeciągnął tutaj całą drogę w dół, ponieważ żadne z powyższych rozwiązań nie zadziałało, i jeśli przedstawiasz widok, który chcesz zmienić przez przejście, możesz to sprawdzić.
Sprawdź typ prezentacji swojego segue. Mój był „poza obecnym kontekstem”. Kiedy zmieniłem go na pełny ekran, zadziałało.
Dzięki @GabLeRoux znalazłem to rozwiązanie.
źródło
Moje wymagania są
AVPlayerViewController
do odtwarzania wideoPodczas odtwarzania wideo, jeśli jest to krajobraz, pozwól ekranowi obracać się poziomo w prawo i poziomo w lewo. Jeśli jest to portret, zablokuj widok tylko w trybie portretowym.
Najpierw zdefiniuj
supportedInterfaceOrientationsForWindow
wAppDelegate.swift
Po drugie, w głównym kontrolerze widoku zdefiniuj następujące funkcje
Następnie musisz przejść do podklasy
AVPlayerViewController
Zastąp te trzy funkcje w programie
MyPlayerViewController.swift
Ponieważ użytkownik może obrócić urządzenie poziomo w lewo lub w prawo, musimy ustawić automatyczne obracanie
Na koniec utwórz
MyPlayerViewController
wystąpienie w kontrolerze widoku i ustaw wartość rozmiaru właściwości.Zainicjuj swojego gracza odpowiednim
videoUrl
, a następnie przypisz go doplayerViewController
. Miłego kodowania!źródło
źródło
Wydaje się, że nadal trwa debata na temat najlepszego wykonania tego zadania, więc pomyślałem, że podzielę się moim (roboczym) podejściem. Dodaj następujący kod do swojej
UIViewController
implementacji:W tym przykładzie będziesz również musiał ustawić dozwolone orientacje urządzeń na „Poziomo po lewej” w ustawieniach projektu (lub bezpośrednio w
info.plist
). Po prostu zmień konkretną orientację, którą chcesz wymusić, jeśli chcesz czegoś innego niżLandscapeLeft.
Kluczem dla mnie było
attemptRotationToDeviceOrientation
wezwanieviewWillAppear
- bez tego widok nie obracałby się prawidłowo bez fizycznego obracania urządzenia.źródło
Według Korey Hinton
Swift 2.2:
Wyłącz rotację
Zablokuj do określonej orientacji
źródło
Wypróbowałem tutaj kilka rozwiązań i ważne jest, aby zrozumieć, że to główny kontroler widoku określi, czy będzie się obracał, czy nie.
Stworzyłem następujący projekt z celem-c github.com/GabLeRoux/RotationLockInTabbedViewChild z działającym przykładem, w
TabbedViewController
którym jeden widok podrzędny może się obracać, a drugi widok podrzędny jest zablokowany w pionie.Nie jest doskonały, ale działa i ten sam pomysł powinien działać w przypadku innych rodzajów widoków głównych, takich jak
NavigationViewController
. :)źródło
Zgodnie z rozwiązaniem pokazanym przez @ sid-sha musisz wszystko umieścić w
viewDidAppear:
metodzie, inaczej nie dostanieszdidRotateFromInterfaceOrientation:
zwolnienia, więc coś takiego:źródło
Moje rozwiązanie
W
AppDelegate
:XXViewController
to ViewController, który chcesz obsługiwać w trybie poziomym.Wtedy rozwiązanie Sunny Shah działałoby w Twojej
XXViewController
na dowolnej wersji iOS:Jest to funkcja narzędziowa do znajdowania najwyższego poziomu ViewController.
źródło
Użyj tego, aby zablokować orientację kontrolera widoku, przetestowaną na IOS 9:
// Zablokuj orientację poziomą w prawo
źródło
Mam ten sam problem i tracę na to tyle czasu. Więc teraz mam swoje rozwiązanie. Moje ustawienie aplikacja jest właśnie wsparcie portret only.However niektóre ekrany do mojego app musi mieć krajobraz only.I naprawić go mieć zmienną isShouldRotate na AppDelegate . I funkcja w AppDelegate :
I wreszcie, gdy ViewControllerA potrzebuje stanu poziomego. Po prostu zrób to: przed wypchnięciem / prezentacją do ViewControllerA przypisz isShouldRotate do true . Nie zapomnij, kiedy wyskakuje / odrzuca przypisanie kontrolera isShouldRotate do false at viewWillDisappear .
źródło
Dla mnie VC najwyższego poziomu potrzebował zaimplementować zastąpień orientacji. Używanie VC w dół stosu nie przyniesie efektu, jeśli górny VC nie jest implementowany.
Słuchany jest tylko VC-Main, zasadniczo w moich testach.
źródło
Wygląda na to, że nawet ty tutaj jest tyle odpowiedzi, że nikt nie był dla mnie wystarczający. Chciałem wymusić orientację, a następnie wrócić do orientacji urządzenia, ale
[UIViewController attemptRotationToDeviceOrientation];
po prostu nie zadziałało. To, co również skomplikowało całą sprawę, to to, że dodałem shouldAutorotate do false na podstawie jakiejś odpowiedzi i nie mogłem uzyskać pożądanych efektów, aby poprawnie obrócić z powrotem we wszystkich scenariuszach.Oto co zrobiłem:
Przed wypchnięciem kontrolera w wywołaniu w jego konstruktorze init:
Zapisuję więc ostatnią orientację urządzenia i rejestruję się na zdarzenie zmiany orientacji. Zdarzenie zmiany orientacji jest proste:
I na widok odrzucenia po prostu wymuszam powrót do dowolnej orientacji, którą mam jako użytkownik.
I to też musi tam być:
A także kontroler nawigacji musi delegować do shouldAutorotate i obsługiwaneInterfaceOrientations, ale wierzę, że większość ludzi już wie.
PS: Przepraszam, używam niektórych rozszerzeń i klas bazowych, ale nazwy są dość znaczące, więc koncepcja jest zrozumiała, stworzy jeszcze więcej rozszerzeń, ponieważ teraz nie jest zbyt ładna.
źródło