2009-04-16 1 views
6

У меня есть UITabBarController, и каждая вкладка обрабатывает другой UIViewController, который при необходимости нажимает на новые контроллеры стека. В двух из этих вкладок мне нужно, когда достигнут определенный контроллер, возможность поворачивать iPhone и визуализировать представление в ландшафтном режиме. После многого боя я обнаружил, что обязательным подклассифицированием UITabBarController является переопределение shouldAutorotateToInterfaceOrientation. Однако, если я просто вернусь ДА в ходе реализации, возникает следующий нежелательный побочный эффект:tabBarController and navigationControllers в ландшафтном режиме, эпизод II

Каждый контроллер на каждой вкладке автоматически помещается в ландшафтном режиме при повороте iPhone.

Даже переопределение должно быть активировано для каждого элемента управления. В каждом контроллере возврат НЕТ не работает: при повороте iPhone контроллер переключается в альбомный режим.

Я реализовал shouldAutorotateToInterfaceOrientation следующим образом в подклассах UITabBarController:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    if([self selectedIndex] == 0 || [self selectedIndex] == 3) 
     return YES; 

    return NO; 
} 

, так что только две вкладки Я заинтересован в самом деле получить поддержку ландшафтного режима. Есть ли способ поддержать ландшафтный режим для конкретного контроллера в стеке определенной вкладки?

Я пытался, но безуспешно, что-то вроде

(BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation {

if([self selectedIndex] == 0 || [self selectedIndex] == 3) 
{ 
    if ([[self selectedViewController] isKindOfClass: [landscapeModeViewController class]]) 
      return YES; 
    } 

    return NO; 

}

Кроме того, я попытался с помощью метода делегата didSelectViewController, без успеха , Любая помощь очень ценится. Спасибо.

ответ

4

Это работает для меня:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    if(self.selectedIndex == 0 && [[[self.viewControllers objectAtIndex:0] visibleViewController] isKindOfClass:[MyViewController class]]) 
     return YES; 
    else 
     return NO; 
} 
+0

Богатый, большое спасибо. Предлагаемое решение работает как шарм ;-) Эта проблема сводила меня с ума! Я не понимал, что правильный способ сделать это также требует одновременной проверки для visibleViewController. Отличный ответ! –

7

Вот расширение UITabBarController, что делегаты призывает shouldAutorotateToInterfaceOrientation к выбранному контроллеру ребенка. Используя это расширение, вам больше не нужно подклассифицировать UITabBarController, и вы можете использовать shouldAutorotateToInterfaceOrientation в своих контроллерах, как и следовало ожидать.

UITabBarController + Autorotate.h:

#import <UIKit/UIKit.h> 

@interface UITabBarController (Autorotate) 
@end 

UITabBarController + Autorotate.m:

#import "UITabBarController+Autorotate.h" 

@implementation UITabBarController (Autorotate) 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    UIViewController *controller = self.selectedViewController; 
    if ([controller isKindOfClass:[UINavigationController class]]) 
     controller = [(UINavigationController *)controller visibleViewController]; 
    return [controller shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
} 

@end 
+1

На самом деле это даже не обязательно. UITabBarController, похоже, делает что-то подобное, но только согласуется с ориентациями, каждый контроллер каждой вкладки поддерживает. – Zargony

+0

Андреас, это будет потрясающая новость! Но я не вижу этого в своем приложении. В моем случае, если я не перейду по запросу к контроллеру вида, запрос на ротацию никогда не пройдет. Как только я его вставляю, сначала запрашивается контроллер панели вкладок, затем я могу размножаться в VC. Если что-то мне не хватает, проконсультируйтесь! На самом деле, я все еще испытываю проблемы, когда VC находится в разделе «Дополнительно» панели вкладок. В этом случае контроллер панели вкладок даже не вызывается. :( –

+0

Я опубликовал свою сагу в новой теме. Http://is.gd/2emkj (перенаправляет обратно на stackoverflow.com) –

3

Я был в состоянии использовать это на некоторое время теперь (от контроллера бар вкладки моего приложения) без проблем:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
} 

Таким образом, в соответствующем ВК, мы получаем, чтобы сделать реальная проверки, в этом случае для вида фотогалереи (что еще?):

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    // Return YES for supported orientations 
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 
} 

Моего вид галереи даже не в топе-оф-стеки для данного Nav контроллера. Его все еще называют.

Увы, я обнаружил, что это не работы так хорошо, когда VC таится внутри MoreViewController (в отличие от четырех основных вкладок). В этом случае моя галерея VC никогда не будет вызвана. Я думаю, это потому, что VC, с которым я звонил, на самом деле является навигационным контроллером с выбранной вкладки, который затем распространяет вещи на соответствующий VC, в этом случае моя фотогалерея VC. Но для The More VC все не так хорошо работает ... aaaand оттуда идет круговым движением вниз. : \

Я попытался использовать модификации Андреаса (см. В других разделах этой нити), но безрезультатно. Добро пожаловать!

+0

Ah-ha! Когда я пытаюсь повернуть интерфейс и ТОЛЬКО, когда я используя VC в контроллере большего размера, я вижу это в своем консольном журнале: «Использование двухступенчатой ​​анимации вращения. Чтобы использовать более плавную одноэтапную анимацию, это приложение должно удалить двухэтапные реализации методов». Umm ... news flash, я НЕ использую двухступенчатую анимацию! То есть я не отвечаю на willAnimateSecondHalfOfRotationFromInterfaceOrientation: duration: вообще. По-видимому, контроллер View больше, и, таким образом, я никогда не получаю вызов willAnimateRotationToInterfaceOrientation: duration:. .. :( –

+0

На самом деле, если я пытаюсь найти версию SecondHalf ... Я тоже не получаю этот вызов. Хмм ... –

2

Я столкнулся с теми же проблемами, что и при работе с UITabBarController. Мне нужно было контролировать, какие UIViewControllers были разрешены для вращения, а какие нет. Моя основная проблема заключалась в закладке MORE. Я не хотел, чтобы любой из UIViewControllers, включенных в вкладку MORE, вращался.

Мое решение было создать свой собственный UITabBarController, который я назвал MyTabBarController:

@interface MyTabBarController : UITabBarController <UITabBarDelegate> { 

} 

Тогда я реализовал метод shouldAutorotateToInterfaceOrientation:

@implementation MyTabBarController 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
UIViewController *controller = [self selectedViewController]; 

if ((controller == [self moreNavigationController]) || ([self selectedIndex] == 4)) 
{ 
    return interfaceOrientation == UIInterfaceOrientationPortrait; 
} 

return [controller shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
} 

@end 

мне нужно, чтобы обнаружить, если была выбрана вкладка MORE. Это двухэтапный процесс; когда сначала выбирается вкладка MORE, API возвращает selectIndex выше 4, поэтому мне нужно сравнить выбранный контроллер с moreNavigationController.

Если UIViewController выбран из вкладки MORE, то выбранноеIndex, наконец, 4, но selectedController больше не является большеNavigationController, но выбран UIViewController.

if ((контроллер == [self большеNavigationController]) || ([self selectedIndex] == 4)) позаботится об этой проблеме.

Теперь, когда я запускаю приложение, мои UIViewControllers на вкладке MORE не вращаются. Надеюсь, это поможет другим разработчикам, которые сталкиваются с теми же проблемами, что и я.

Emilio

+0

Спасибо. Я должен был реализовать это, потому что я программировал программный контроллер tabbar и кажется, что он не мог " t найти метод shouldAutorotateToInterfaceOrientation, даже если он определен на том же контроллере view или appdelegate. Я должен был это поддержать изменение ориентации на iOS5, не обязательно на iOS6 – estemendoza

0

Спасибо, спасибо, спасибо. Это было 2 дня, чтобы выяснить, как это сделать. Здесь я беру на себя всю вашу большую помощь, когда у вас есть tabBarController с navigationControllers.

- (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation {

UIViewController *controller = self.selectedViewController; 
if ([controller isKindOfClass:[UINavigationController class]]) 
    controller = [(UINavigationController *)controller visibleViewController]; 

if([controller isKindOfClass:[LOCviewcontroller class]]) 
    return YES; 
else 
    if([controller isKindOfClass:[personWebSiteView class]]) 
     return YES; 
else return NO; 

}

Любая критика кодогенератора neophite кодировщика всегда ценится ... Джек

0

Действительно ли ОК подкласс UITabBarController (как указано в принятом ответе выше)?

Я понял, что Яблоки говорят что-то вроде «вы никогда не должны подкласса UITabBarController или UINavigationController» - или я неправильно понял?

В любом случае; Я нашел this tutorial, где они подклассифицируют UIViewController, в который они помещают UITabBarController.

1

Из того, что я видел здесь и в других местах, я сшил решение, использующее метод shouldAutorotate, поскольку старый shouldAutorotateToInterfaceOrientation устарел.

Я разместил его внутри категории для UITabBarController. Я так надеюсь, что это допустимо!

// call to method shouldAutorotate replaces call to method shouldAutorotateToInterfaceOrientation (deprecated) 
-(BOOL)shouldAutorotate 
{ // check whether selected view controller should autorotate  
    UIViewController *controller = self.selectedViewController; 
    if ([controller isKindOfClass:[UINavigationController class]]) 
    { // in case it is a navigation controller: get visible view of that 
     controller = [(UINavigationController *)controller visibleViewController]; 
    } 
    return [controller shouldAutorotate]; 
} 
Смежные вопросы