17

Mam aplikację na iPhone aktualizuję do iOS 6, która ma problemy z rotacją. Mam UITabBarController z 16 UINavigationCotrollers. Większość elementów podrzędnych może pracować w układzie pionowym lub krajobrazowym, ale niektóre z nich to tylko portret. Z iOS 6 rzeczy obracają się, kiedy nie powinny.iOS 6 UITabBarController obsługiwana orientacja z bieżącym kontrolerem UINavigation

Próbowałem instacji TabBarController zwrócić supportedInterfaceOrienations bieżącego navigationController w wybranym viewController:

- (NSUInteger)supportedInterfaceOrientations{ 

    UINavigationController *navController = (UINavigationController *)self.selectedViewController; 
    return [navController.visibleViewController supportedInterfaceOrientations]; 
} 

To dało mi bliżej. Kontroler widoku nie obróci się poza pozycję, gdy jest widoczny, ale jeśli jestem na poziomych i przełączanych kartach, nowa karta będzie w krajobrazie, nawet jeśli nie jest obsługiwana.

Idealnie aplikacja będzie dostępna tylko w obsługiwanym wyglądzie bieżącego kontrolera widocznego widoku. Jakieś pomysły?

Odpowiedz

58

podklas twoi UITabBarController nadrzędne te metody:

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    // You do not need this method if you are not supporting earlier iOS Versions 
    return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
} 

-(NSUInteger)supportedInterfaceOrientations 
{ 
    return [self.selectedViewController supportedInterfaceOrientations]; 
} 

-(BOOL)shouldAutorotate 
{ 
    return YES; 
} 

podklas twoi UINavigationController nadrzędne następujących metod:

-(NSUInteger)supportedInterfaceOrientations 
{ 
    return [self.topViewController supportedInterfaceOrientations]; 
} 

-(BOOL)shouldAutorotate 
{ 
    return YES; 
} 

następnie wdrożyć te metody w swoim viewControllers że nie chcesz, aby obrócić:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 

-(BOOL)shouldAutorotate 
{ 
    return NO; 
} 

-(NSUInteger)supportedInterfaceOrientations 
{ 
    return UIInterfaceOrientationMaskPortrait; 
} 

A dla viewControllers które chcą obracać:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
    { 
     return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 
    } 

    -(NSUInteger)supportedInterfaceOrientations 
    { 
     return UIInterfaceOrientationMaskAllButUpsideDown; 
    } 

    -(BOOL)shouldAutorotate 
    { 
     return YES; 
    } 

Twój TabBarController powinien być dodany jako RootviewController okna aplikacji. Jeśli planujesz wspierać domyślne orientacje, wszystkie oprócz uproszczonego są domyślne dla iPhone'a, to nie musisz robić nic więcej. Jeśli chcesz wspierać do góry nogami lub jeśli nie chcesz obsługiwać innych orientacji, musisz ustawić odpowiednie wartości w delegatach aplikacji i/lub w pliku info.plist.

+7

To prawie dla mnie działa. Problem polega na tym, że jestem już w krajobrazie, kiedy przełączam zakładki na portret, ale wciąż jest krajobraz. Obrotowy portret naprawia go i nie będzie się obracał z powrotem w krajobraz, ale nadal potrzebuję go portretować, gdy pierwszy raz się załaduje. – Ryan

+0

Nie jestem pewien, co dokładnie trzeba zrobić, aby go obrócić, ale założę się, że robisz to w - (void) viewWillLayoutSubviews. Może nie być dokładnie z tą nazwą metody z pamięci. Moje własne widoki, w których użyłem tego kodu, zmieniają się całkowicie po obróceniu i używam tej metody do ponownego skonfigurowania ich z powrotem do trybu portretu. Możesz także wypróbować coś w -viewWillDisappear. Może [self.view setNeedsDisplay]. Nie jestem w Xcode w tej chwili, więc są to po prostu pomysły, które chciałbym zbadać w twoim przypadku. –

+0

Nice! Działa jak marzenie! – Dennso

5

Miałem problem z tym, że niektóre kontrolery View w stosie nawigacji obsługują wszystkie orientacje, niektóre tylko portretem, ale UINavigationController zwróciło wszystkie orientacje obsługiwane przez aplikację, ten mały hack pomógł mi. Nie jestem pewien, czy to ma zachowanie lub co

@implementation UINavigationController (iOS6OrientationFix) 

-(NSUInteger) supportedInterfaceOrientations { 
    return [self.topViewController supportedInterfaceOrientations]; 
} 

@end 
+0

zrozumieć, jak ten hack pomógł ci mieć różne zachowania na różnych kontrolerach widoków jednego kontrolera nawigacyjnego. Tak jak wiem, ten hack zostanie wykonany tylko raz, więc wszystkie widoki kontrold będą zachowywać się tak samo jak topViewController. Hing? –

+1

ten kod jest wykonywany za każdym razem, gdy urządzenie zmienia orientację, więc zwróci obsługiwane orientacje, dla których kiedykolwiek kontroler uiview jest aktualnie aktywny i widoczny w chwili obecnej – Mindaugas

+0

działa to świetnie. dzięki –

3

moim zdaniem jest lepsze coś takiego (jako metody kategorii)

-(NSUInteger) supportedInterfaceOrientations { 
    if([self.topViewController respondsToSelector:@selector(supportedInterfaceOrientations)]) 
    { 
     return [self.topViewController supportedInterfaceOrientations]; 
    } 
    return UIInterfaceOrientationMaskPortrait; 
} 

ten zapewnia, że ​​metoda jest stosowana. Jeśli tego nie zrobisz, a metoda nie zostanie zaimplementowana (jak w iOS5 env), aplikacja powinna się zawiesić!

0

Jeśli planujesz włączyć lub wyłączyć rotację dla wszystkich kontrolerów widoku, nie potrzebujesz podklasy UINavigationController. Zamiast używać:

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 

w swoją AppDelegate.

Jeśli zamierzasz obsługiwać wszystkie kierunki w swojej aplikacji, ale różne orientacje na RODZICÓW Zobacz Sterowniki (UINavigationController stosu na przykład) należy użyć

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 

z AppDelegate w połączeniu z następujących metod rodzica View Controller .

- (BOOL)shouldAutorotate 

i

- (NSUInteger)supportedInterfaceOrientations 

Ale jeśli planujesz mieć różne ustawienia orientacji w różnych DZIECI ViewControllers w tym samym stosie nawigacji (jak ja), trzeba sprawdzić aktualną ViewController w stosie nawigacji.

Utworzyłem następujących w moim UINavigationController podklasy:

- (BOOL)shouldAutorotate 
{ 
    return YES; 
} 

- (NSUInteger)supportedInterfaceOrientations 
{ 
    int interfaceOrientation = 0; 

    if (self.viewControllers.count > 0) 
    { 
     DLog(@"%@", self.viewControllers); 
     for (id viewController in self.viewControllers) 
     { 
      if ([viewController isKindOfClass:([InitialUseViewController class])]) 
      { 
       interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; 
      } 
      else if ([viewController isKindOfClass:([MainViewController class])]) 
      { 
       interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; 
      } 
      else 
      { 
       interfaceOrientation = UIInterfaceOrientationMaskAllButUpsideDown; 
      } 
     } 
    } 
    return interfaceOrientation; 
} 

Ponieważ nie można kontrolować już od dziecięcych ViewControllers ustawieniami obrotu prezentowane kontrolera widoku Musisz jakoś przechwycić co widok kontroler jest obecnie w stosie nawigacji . Tak właśnie zrobiłem :). Mam nadzieję, że pomaga!

Powiązane problemy