Ponieważ ShouldAutorotateToInterfaceOrientation
jest on przestarzały w iOS 6 i użyłem go do wymuszenia tylko portretu określonego widoku , jaki jest właściwy sposób zrobienia tego w iOS 6? Dotyczy to tylko jednego obszaru mojej aplikacji, wszystkie inne widoki mogą się obracać.
ios
xcode
ios6
xamarin.ios
Neal
źródło
źródło
Najlepszy sposób na iOS6 został opisany w artykule „Samouczki iOS6 By Tutorials” zespołu Ray Wenderlich - http://www.raywenderlich.com/ i
UINavigationController
w większości przypadków jest lepszy niż tworzenie podklas .Używam iOS6 z scenorysem, który zawiera
UINavigationController
zestaw jako początkowy kontroler widoku.//AppDelegate.m - ta metoda nie jest niestety dostępna przed iOS6
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{ NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown; if(self.window.rootViewController){ UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject]; orientations = [presentedViewController supportedInterfaceOrientations]; } return orientations; }
//MyViewController.m - zwróć dowolne orientacje, które chcesz obsługiwać dla każdej z nich
UIViewController
- (NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait; }
źródło
Ta odpowiedź odnosi się do pytań zadanych w komentarzach do postu PO:
Aby wymusić pojawienie się widoku w określonej orientacji, w viewWillAppear umieść następujące elementy:
UIApplication* application = [UIApplication sharedApplication]; if (application.statusBarOrientation != UIInterfaceOrientationPortrait) { UIViewController *c = [[UIViewController alloc]init]; [self presentModalViewController:c animated:NO]; [self dismissModalViewControllerAnimated:NO]; }
Trochę to hack, ale to zmusza
UIViewController
do przedstawienia portretu, nawet jeśli poprzedni kontroler był krajobrazemUPDATE dla iOS7
Powyższe metody są teraz przestarzałe, więc w przypadku iOS 7 użyj następujących:
UIApplication* application = [UIApplication sharedApplication]; if (application.statusBarOrientation != UIInterfaceOrientationPortrait) { UIViewController *c = [[UIViewController alloc]init]; [c.view setBackgroundColor:[UIColor redColor]]; [self.navigationController presentViewController:c animated:NO completion:^{ [self.navigationController dismissViewControllerAnimated:YES completion:^{ }]; }]; }
Co ciekawe, w chwili pisania tego tekstu albo teraźniejszość, albo zwolnienie muszą być animowane. Jeśli żadna z nich nie jest, otrzymasz biały ekran. Nie mam pojęcia, dlaczego to działa, ale działa! Efekt wizualny różni się w zależności od tego, który jest animowany.
źródło
Więc napotkałem ten sam problem podczas wyświetlania portretów tylko w widokach modalnych. Normalnie utworzyłbym
UINavigationController
, ustawiłbymviewController
jakorootViewController
, a następnie wyświetlałUINavigationController
jako widok modalny. Ale z iOS 6viewController
zapyta teraz navigationController o obsługiwane orientacje interfejsu (który domyślnie jest teraz przeznaczony dla iPada i wszystkiego, ale do góry nogami dla iPhone'a).Rozwiązanie : musiałem podklasować
UINavigationController
i nadpisać metody autorotacji. Trochę kiepski.- (BOOL)shouldAutorotate { return NO; } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } // pre-iOS 6 support - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { return (toInterfaceOrientation == UIInterfaceOrientationPortrait); }
źródło
IOS 5
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{ return (interfaceOrientation == UIInterfaceOrientationPortrait); }
IOS 6
-(BOOL)shouldAutorotate{ return YES; } -(NSInteger)supportedInterfaceOrientations{ // UIInterfaceOrientationMaskLandscape; // 24 // // UIInterfaceOrientationMaskLandscapeLeft; // 16 // // UIInterfaceOrientationMaskLandscapeRight; // 8 // // UIInterfaceOrientationMaskPortrait; // 2 // return UIInterfaceOrientationMaskPortrait; // or return 2; }
źródło
Nie zgadzam się z odpowiedzią @aprato, ponieważ metody rotacji UIViewController są zadeklarowane w samych kategoriach, co powoduje niezdefiniowane zachowanie, jeśli zastąpisz to w innej kategorii. Bezpieczniej jest je zastąpić w podklasie UINavigationController (lub UITabBarController)
Nie obejmuje to również scenariusza, w którym wypychasz / prezentujesz / pop z widoku poziomego do portretu tylko VC lub odwrotnie. Aby rozwiązać ten trudny problem (nigdy nie rozwiązany przez Apple), należy:
W iOS <= 4 i iOS> = 6:
UIViewController *vc = [[UIViewController alloc]init]; [self presentModalViewController:vc animated:NO]; [self dismissModalViewControllerAnimated:NO]; [vc release];
W iOS 5:
UIWindow *window = [[UIApplication sharedApplication] keyWindow]; UIView *view = [window.subviews objectAtIndex:0]; [view removeFromSuperview]; [window addSubview:view];
To NAPRAWDĘ zmusi UIKit do ponownej oceny wszystkich Twoich powinienAutorotate, obsługiwaneInterfaceOrientations itp.
źródło
Mam bardzo dobre podejście do mieszania https://stackoverflow.com/a/13982508/2516436 i https://stackoverflow.com/a/17578272/2516436
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{ NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown; if(self.window.rootViewController){ UIViewController *presentedViewController = [self topViewControllerWithRootViewController:self.window.rootViewController]; orientations = [presentedViewController supportedInterfaceOrientations]; } return orientations; } - (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController { if ([rootViewController isKindOfClass:[UITabBarController class]]) { UITabBarController* tabBarController = (UITabBarController*)rootViewController; return [self topViewControllerWithRootViewController:tabBarController.selectedViewController]; } else if ([rootViewController isKindOfClass:[UINavigationController class]]) { UINavigationController* navigationController = (UINavigationController*)rootViewController; return [self topViewControllerWithRootViewController:navigationController.visibleViewController]; } else if (rootViewController.presentedViewController) { UIViewController* presentedViewController = rootViewController.presentedViewController; return [self topViewControllerWithRootViewController:presentedViewController]; } else { return rootViewController; } }
i zwróć dowolne orientacje, które chcesz obsługiwać dla każdego UIViewController
- (NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait; }
źródło
Mam stosunkowo złożoną uniwersalną aplikację używającą UISplitViewController i UISegmentedController i mam kilka widoków, które muszą być przedstawione w krajobrazie przy użyciu
presentViewController
. Korzystając z metod sugerowanych powyżej, udało mi się sprawić, by iPhone ios 5 i 6 działał poprawnie, ale z jakiegoś powodu iPad po prostu odmówił przedstawienia jako Krajobraz. Wreszcie znalazłem proste rozwiązanie (wdrożone po wielu godzinach czytania i prób i błędów), które działa zarówno na urządzeniach, jak i na iOS 5 i 6.Krok 1) Na kontrolerze określ wymaganą orientację (mniej więcej jak wspomniano powyżej)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationLandscapeRight); } -(BOOL)shouldAutorotate { return YES; } -(NSUInteger)supportedInterfaceOrientations { NSInteger mask = UIInterfaceOrientationMaskLandscape; return mask; }
Krok 2) Utwórz prostą podklasę UINavigationController i zaimplementuj następujące metody
-(BOOL)shouldAutorotate { return YES; } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscape; }
Krok 3) Przedstaw swój viewController
vc = [[MyViewController alloc]init]; MyLandscapeNavigationController *myNavigationController = [[MyLandscapeNavigationController alloc] initWithRootViewController:vc]; [self myNavigationController animated:YES completion:nil];
Mam nadzieję, że to komuś pomoże.
źródło
Nie żeby tu nudno, ale czy zechciałbyś podzielić się swoją podklasą? Dziękuję Ci.
edycja: cóż, w końcu to zrobiłem, podklasa była bardzo prosta do wykonania. Po prostu musiałem zadeklarować
navigationController
wAppDelegate
asUINavigationControllerSubclass
zamiast domyślnejUINavigationController
, a następnie zmodyfikowałem twoją podklasę za pomocą:- (BOOL)shouldAutorotate { return _shouldRotate; }
więc mogę ustawić dowolny widok, który chcę obrócić lub nie, dzwoniąc pod numer
viewDidLoad
_navController = (UINavigationController *)self.navigationController; [_navController setShouldRotate : YES / NO]
Mam nadzieję, że ta zmiana pomoże również innym. Dzięki za wskazówkę!
Wskazówka: skorzystaj z
- (NSUInteger)supportedInterfaceOrientations
w kontrolerach widoku, więc nie będziesz mieć pożądanego widoku portretu w poziomie lub odwrotnie.
źródło
Nie testowałem tego sam, ale dokumentacja stwierdza, że możesz teraz zastąpić te metody:
supportedInterfaceOrientations
ipreferredInterfaceOrientationForPresentation
.Prawdopodobnie możesz osiągnąć to, co chcesz, ustawiając tylko taką orientację, jaką chcesz w tych metodach.
źródło
Odpowiedzi przy użyciu podklas lub kategorii, aby umożliwić VC w klasach UINavigationController i UITabBarController, działają dobrze. Uruchamianie trybu pionowego z poziomu kontrolera z paskiem kart nie powiodło się. Jeśli musisz to zrobić, użyj triku wyświetlania i ukrywania nieanimowanego widoku modalnego, ale zrób to w metodzie viewDidAppear . Nie działało to dla mnie w viewDidLoad lub viewWillAppear.
Poza tym powyższe rozwiązania działają dobrze.
źródło
W przypadku Monotouch możesz to zrobić w ten sposób:
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations() { return UIInterfaceOrientationMask.LandscapeRight; } public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation() { return UIInterfaceOrientation.LandscapeRight; }
źródło
Widzę wiele odpowiedzi, ale nie rozumiem konkretnego pomysłu i odpowiedzi na temat orientacji, ale widzę, że link dobrze rozumie orientację i usuwa wymuszony obrót dla ios6.
http://www.disalvotech.com/blog/app-development/iphone/ios-6-rotation-solution/
Myślę, że to pełna pomoc.
źródło
Po prostu przejdź do project.plist, a następnie dodaj Obsługiwaną orientację interfejsu, a następnie dodaj tylko Portret (dolny przycisk strony głównej) i Portret (górny przycisk strony głównej).
Możesz dodać lub usunąć tam orientację zgodnie z wymaganiami projektu.
Dzięki
źródło
1) Sprawdź ustawienia projektu i info.plist i upewnij się, że wybrano tylko te orientacje, które chcesz.
2) Dodaj następujące metody do najwyższego kontrolera widoku (kontroler nawigacji / kontroler z zakładkami)
- (NSUInteger) supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; }
3) Dodaj następujące metody do delegata aplikacji
- (NSUInteger) supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { return UIInterfaceOrientationMaskPortrait; }
źródło
Umieść to w pliku .m każdego,
ViewController
którego nie chcesz obracać:- (NSUInteger)supportedInterfaceOrientations { //return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft; return UIInterfaceOrientationMaskPortrait; }
Więcej informacji znajdziesz tutaj .
źródło