tabBarController и navigationControllers в ландшафтном режиме, эпизод II - PullRequest
6 голосов
/ 16 апреля 2009

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

каждый контроллер на каждой вкладке автоматически переводится в альбомный режим при повороте iPhone.

Даже переопределение ifAutorotateToInterfaceOrientation в каждом контроллере для возврата NO не работает: при повороте iPhone контроллер переводится в альбомный режим.

Я реализовал долженAutorotateToInterfaceOrientation следующим образом в подклассе 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. Любая помощь очень ценится. Спасибо.

Ответы [ 7 ]

7 голосов
/ 31 июля 2009

Вот расширение 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
4 голосов
/ 21 апреля 2009

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

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    if(self.selectedIndex == 0 && [[[self.viewControllers objectAtIndex:0] visibleViewController] isKindOfClass:[MyViewController class]])
        return YES;
    else
        return NO;
}
3 голосов
/ 13 августа 2009

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

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

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

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

Мой вид галереи даже не на вершине стека для данного Nav Controller. Это все еще называют.

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

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

2 голосов
/ 09 января 2010

Я столкнулся с теми же проблемами, что и вы, работая с UITabBarController. Мне нужно было контролировать, какие UIViewControllers было разрешено вращать, а какие нет. Моя главная проблема была с вкладкой БОЛЬШЕ. Я не хотел, чтобы какой-либо из контроллеров 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, API возвращает selectedIndex выше 4, поэтому мне нужно было сравнить выбранный контроллер с moreNavigationController.

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

if ((controller == [self moreNavigationController]) || ([self selectedIndex] == 4)) решает эту проблему.

Теперь, когда я запускаю свое приложение, мои UIViewControllers на вкладке БОЛЬШЕ не поворачиваются. Я надеюсь, что это поможет другим разработчикам, которые сталкиваются с теми же проблемами, что и я.

Emilio

1 голос
/ 04 апреля 2013

Из того, что я видел здесь и в других местах, я соединил решение, которое использует метод 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];
}
0 голосов
/ 18 февраля 2011

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

Я понял, что Яблоко говорит что-то вроде "никогда не следует создавать подкласс UITabBarController или UINavigationController" - или я неправильно понял?

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

0 голосов
/ 05 августа 2010

Спасибо, Спасибо, Спасибо. Это было 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; 

}

Любая критика кода неофитного кодера всегда ценится ... jack

...