【问题标题】:tabBarController and navigationControllers in landscape mode, episode II横向模式下的 tabBarController 和 navigationControllers,第二集
【发布时间】:2010-10-19 21:12:21
【问题描述】:

我有一个 UITabBarController,每个选项卡都处理一个不同的 UIViewController,它根据需要将新控制器推送到堆栈上。在其中两个选项卡中,当到达特定控制器时,我需要旋转 iPhone 并在横向模式下可视化视图的能力。经过一番挣扎后,我发现强制继承 UITabBarController 来覆盖 shouldAutorotateToInterfaceOrientation。但是,如果我在实现中简单地返回 YES,则会出现以下不良副作用:

旋转 iPhone 时,每个选项卡中的每个控制器都会自动进入横向模式。

即使在每个控制器中覆盖 shouldAutorotateToInterfaceOrientation 以返回 NO 也不起作用:当 iPhone 旋转时,控制器处于横向模式。

我在子类UITabBarController中实现了shouldAutorotateToInterfaceOrientation如下:

- (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,但没有成功。 任何帮助是极大的赞赏。 谢谢。

【问题讨论】:

    标签: iphone uiviewcontroller uitabbarcontroller landscape


    【解决方案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];
    }
    

    【讨论】:

      【解决方案2】:

      继承 UITabBarController 真的可以吗(如上面接受的答案中所建议的那样)?

      我知道 Apples 说过“你永远不应该继承 UITabBarController 或 UINavigationController”之类的话——还是我误解了?

      无论如何;我找到了this tutorial,他们在其中子类化了一个 UIViewController,并在其中放置了一个 UITabBarController。

      【讨论】:

        【解决方案3】:

        谢谢,谢谢,谢谢。弄清楚如何做到这一点已经有 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; 
        

        }

        任何对新手编码员代码的批评总是受到赞赏...杰克

        【讨论】:

          【解决方案4】:

          我在使用 UITabBarController 时遇到了与您相同的问题。我需要控制哪些 UIViewController 可以旋转,哪些不可以。我的主要问题是更多选项卡。我不希望 MORE 选项卡中包含的任何 UIViewController 旋转。

          我的解决方案是创建自己的 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 返回一个大于 4 的 selectedIndex,因此我需要将所选控制器与 moreNavigationController 进行比较。

          如果从 MORE 选项卡中选择了 UIViewController,则 selectedIndex 最终为 4,但 selectedController 不再是 moreNavigationController,而是选择了 UIViewController。

          if ((controller == [self moreNavigationController]) || ([self selectedIndex] == 4)) 解决了这个问题。

          现在,当我运行我的应用程序时,我的 MORE 选项卡中的 UIViewControllers 不会旋转。我希望这将帮助其他遇到与我相同问题的开发人员。

          埃米利奥

          【讨论】:

          • 谢谢。我必须实现这一点,因为我正在以编程方式创建我的 tabbarcontroller,它似乎找不到 shouldAutorotateToInterfaceOrientation 方法,即使它在同一个 viewcontroller 或 appdelegate 上定义。我不得不这样做以支持 iOS5 上的方向更改,而在 iOS6 上则不需要
          【解决方案5】:

          我已经可以使用它一段时间了(从我的应用的标签栏控制器)没有问题:

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

          这样,在适当的 VC 中,我们可以进行真实检查,在本例中是针对照片库视图(还有什么?):

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

          对于给定的导航控制器,我的画廊视图甚至不在堆栈顶部。它仍然会被调用。

          唉,我刚刚发现当 VC 潜伏在 MoreViewController 中(而不是四个主要选项卡)时,这 并没有 工作得很好。在这种情况下,我的画廊 VC 永远不会被调用。我认为这是因为我一直在调用的 VC 实际上是所选选项卡中的导航控制器,然后将内容传播到适当的 VC,在本例中是我的照片库 VC。但是对于 More VC 来说,事情并没有那么顺利...... aaaand 事情从那里轮流走下坡路。 :\

          我尝试使用 Andreas 的修改(请参阅此线程的其他地方),但无济于事。欢迎提供线索!

          【讨论】:

          • 啊哈!当我尝试旋转界面时,并且仅当我在更多视图控制器中使用 VC 时,我在控制台日志中看到:“使用两阶段旋转动画。要使用更平滑的单阶段动画,此应用程序必须删除两阶段方法实现。”嗯...新闻快讯,我没有使用两阶段动画!也就是说,我根本没有回应 willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration: 。显然更多视图控制器是,因此我永远不会调用 willAnimateRotationToInterfaceOrientation:duration: ... :(
          • 事实上,如果我尝试寻找 SecondHalf 版本......我也没有接到那个电话。嗯...
          【解决方案6】:

          这是对 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
          

          【讨论】:

          • 其实这甚至没有必要。 UITabBarController 似乎做了类似的事情,但只同意方向,每个选项卡的每个控制器都支持。
          • 安德烈亚斯,那将是个好消息!但我没有在我的应用程序中看到这一点。就我而言,除非我将请求移至视图控制器,否则旋转请求永远不会通过。一旦我把它放进去,Tab Bar 控制器就会被首先询问,然后我就可以传播到 VC。如果有什么我遗漏的,请指教!事实上,当 VC 位于选项卡栏的“更多”部分时,我仍然遇到问题。在这种情况下,Tab Bar 控制器甚至不会被调用。 :(
          • 我已经在一个新线程中发布了我的传奇。 is.gd/2emkj(重定向回 stackoverflow.com)
          【解决方案7】:

          这对我有用:

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

          【讨论】:

          • 丰富,非常感谢。提议的解决方案就像一个魅力;-)这个问题让我发疯了!我没有意识到执行此操作的正确方法还需要同时检查 visibleViewController。很好的答案!
          猜你喜欢
          • 2012-12-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多