Вопрос

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

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

Даже переопределение mustAutorotateToInterfaceOrientation в каждом контроллере для возврата NO не работает:когда iPhone поворачивается, контроллер переходит в ландшафтный режим.

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

Это было полезно?

Решение

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

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

Другие советы

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

UITabBarController+Автоповорот.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

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

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

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

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

Представление моей галереи даже не находится на вершине стека для данного контроллера навигации.Его все равно вызывают.

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

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

Я столкнулся с теми же проблемами, что и вы, при работе с UITabBarController.Мне нужно было контролировать, каким UIViewControllerм разрешено вращаться, а каким нет.Моя основная проблема была с вкладкой БОЛЬШЕ.Я не хотел, чтобы какой-либо из UIViewControllers, включенных в вкладку «БОЛЬШЕ», вращался.

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

@interface MyTabBarController : UITabBarController <UITabBarDelegate> {

}

Затем я реализовал метод mustAutorotateToInterfaceOrientation:

@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

Мне нужно было узнать, выбрана ли вкладка «БОЛЬШЕ».Это двухэтапный процесс;когда изначально выбрана вкладка «БОЛЬШЕ», API возвращает selectedIndex выше 4, поэтому мне нужно было сравнить выбранный контроллер с moreNavigationController.

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

А if ((controller == [self moreNavigationController]) || ([self selectedIndex] == 4)) занимается этим вопросом.

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

Эмилио

Из того, что я видел здесь и в других местах, я собрал решение, использующее метод 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];
}

Спасибо Спасибо спасибо.2 дня раздумывал как это сделать.Вот мое мнение о вашей огромной помощи, когда у вас есть tabBarController с навигационными контроллерами.

-(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; 

}

Любая критика кода программиста-новичка всегда приветствуется... Джек

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top