【问题标题】:How do I rotate only some views when working with a uinavigationcontroller as a tab of a uitabbarcontroller将 uinavigationcontroller 用作 uitabbarcontroller 的选项卡时,如何仅旋转某些视图
【发布时间】:2010-04-27 00:33:00
【问题描述】:

这是一个我无法弄清楚如何工作的流程。 (当我声明(工作)时,这意味着在当前状态下,该视图的方向规则正常工作)

第一个视图:UINavigationController 堆栈上的 TableView,它是 UITabBarController 的选项卡。

TableView 只能是纵向的。 (在职的) 当您将 TableView 旋转为横向时,模态会出现一个自定义 UIView,它就像一个封面流(我稍后会解释那里的问题)。

在 tableview 上进行的选择会将 UIScrollview 推入堆栈。

UIScrollView 允许所有方向。 (工作)

当 UIScrollView 处于横向模式并且用户回击时,他们将被带到自定义 UIView,这类似于封面流并且只允许横向。

问题就在这里。因为 UIScrollView 允许完全旋转,所以它允许 TableView 旋转以及横向。

我有一个附加到通知“UIDeviceOrientationDidChangeNotification”的方法,该方法检查自定义视图是否是当前控制器,如果是,如果用户已旋转回纵向,我需要弹出自定义视图并显示表格查看。

表格视图必须旋转回纵向,只要用户看不到它就可以了。当我创建自定义动画时,它的效果非常好,除了一些奇怪的不可见黑框,它似乎在我将自定义视图淡出到 tableview 之前随着设备旋转。

进一步为了确保我的 tableview 将旋转到纵向,我必须允许 customview 支持所有方向,因为系统会查看当前视图(在我的代码中)是否允许该应用旋转到一定的方向。因此,我提出的许多解决方案都会在表格视图重新聚焦时显示 customview 旋转为纵向。

我的另一个问题非常相似。如果您正在查看 tableview 并旋转 customview 的 modalview 。当您在此视图上进行选择时,它会将 UIScrollview 推送到堆栈上,但由于 Tableview 仅支持纵向,因此 UIScrollview 在设备处于横向模式时以纵向显示。

我怎样才能克服这些可怕的障碍?

这是我目前的尝试:

在使用 UITabBarController 时,系统实际上只关心 tabbarcontroller 对旋转的看法。

目前,每当加载视图时,它都会报告它支持的方向。

TabBarController.m

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
switch (self.supportedOrientation) {
    case SupportPortraitOrientation:
        [[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES]; 
        return (interfaceOrientation == UIInterfaceOrientationPortrait);
        break;
    case SupportPortraitUpsideDownOrientation:
        [[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES]; 
        return (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
        break;
    case SupportPortraitAllOrientation:
        [[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES]; 
        return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
        break;
    case SupportLandscapeLeftOrientation:
        [[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES]; 
        return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
        break;
    case SupportLandscapeRightOrienation:
        [[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];            
        return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
        break;
    case SupportLandscapeAllOrientation:
        [[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES]; 
        return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight);
        break;
    case SupportAllOrientation:
        if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
            [[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES]; 
        }else {
            //[[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES]; 
        }
        return YES;
        break;
    default:
        return (interfaceOrientation == UIInterfaceOrientationPortrait);
        break;
    }

}

此代码块是我的 UINavigationController 的一部分,并且位于响应 UIDeviceOrientationDidChangeNotification 通知的方法中。它负责弹出customview并显示tableview。有两个不同的版本,最初用于两个不同版本的 SDK,但两者都非常接近解决方案。

第一个在 3.0 上不受支持的原因是由于某种原因您不能让视图显示然后显示为模态视图。不确定这是错误还是功能。

第二种解决方案效果很好,只是我看到一个外盒围绕着 iphone 旋转。

if ([[self topViewController] isKindOfClass:FlowViewController.class]) {
    NSString *iphoneVersion = [[UIDevice currentDevice] systemVersion];
    double version = [iphoneVersion doubleValue];
    if(version > 3.0){ //1st solution
        //if the delivered app is not built with the 3.1 SDK I don't think this will happen anyway
        //we need to test this
        [self presentModalViewController:self.flowViewController animated:NO];
        //[self toInterfaceOrientation:UIDeviceOrientationPortrait animated:NO];
        [self popViewControllerAnimated:NO];
        [self setNavigationBarHidden:NO animated:NO];
        [self dismissModalViewControllerAnimated:YES];
    }else{ //2nd solution
        DLog(@"3.0!!");
        //[self toInterfaceOrientation:UIDeviceOrientationPortrait animated:NO];
        CATransition *transition = [CATransition animation];
        transition.duration = 0.50;
        transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        transition.type = kCATransitionPush;
        transition.subtype = kCATransitionFade;

        CATransition *tabBarControllerLayer = [CATransition animation];
        tabBarControllerLayer.duration = 0.50;
        tabBarControllerLayer.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        tabBarControllerLayer.type = kCATransitionPush;
        tabBarControllerLayer.subtype = kCATransitionFade;

        [self.tabBarController.view.layer addAnimation:transition forKey:kCATransition];
        [self.view.layer addAnimation:transition forKey:kCATransition];
        [self popViewControllerAnimated:NO];
        [self setNavigationBarHidden:NO animated:NO];

    }
    [self performSelector:@selector(resetFlow) withObject:nil afterDelay:0.75];

}

我几乎确信除了手动旋转会打乱键盘旋转之外没有其他解决方案。

任何建议将不胜感激!

谢谢。

【问题讨论】:

    标签: iphone uinavigationcontroller uitabbarcontroller rotation orientation


    【解决方案1】:

    如果您在标签栏控制器中有一个导航控制器,并且您只想允许某些视图旋转,我有解决方案。它可能并不适合所有人,也可能不是最干净的代码,但到目前为止它是唯一的解决方案。

    此外,此方法假定您在离开第一个视图时不想看到标签栏,尽管您可以使用 popOverControllers 实现我的解决方案,但我不确定。

    创建标签栏控制器 创建导航控制器 创建第二个不在标签栏控制器上的导航控制器 将第一个导航控制器放在标签栏控制器中 配置将 pushViewController 到第一个的方法:

    截取当前屏幕的屏幕截图。 将该屏幕截图放入 UIViewController 将该 UIViewController 推到第二个导航控制器上 模态显示第二个导航控制器 在大约 0.15 秒的延迟后,将想要的视图控制器推送到第二个导航控制器的导航堆栈上。

    现在您的当前控制器已脱离 tabBarcontroller 并且它的旋转(因为此导航控制器以模态方式呈现)独立于 tabBarController!

    您必须做一些工作才能回到您的第一个视图,但这并不难。

    这是一个详细的解决方案,我会在一段时间内尝试编写代码。他们更多的是这个答案,但这应该足以让你开始,如果你需要帮助,请告诉我。

    【讨论】:

      【解决方案2】:

      您可以尝试所有这些:

      我在每个视图中都使用这条线,因此您可以在任何视图中更改首选方向:

      - (BOOL)shouldAutorotate
      {
          return YES;
      }
      
      - (NSUInteger)supportedInterfaceOrientations
      {
          if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
              return UIInterfaceOrientationMaskPortrait;
          } else {
              return UIInterfaceOrientationMaskAll;
          }
      }
      
      - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
      {
          return UIInterfaceOrientationPortrait;
      }
      

      然后你必须继承 UINavigationController 和 UITabBarController,所以这里是代码:

      //cCustomNavigationController.h file
      
      #import <UIKit/UIKit.h>
      
      @interface cCustomNavigationController : UINavigationController <UINavigationControllerDelegate>
      
      @end
      
      //cCustomNavigationController.m file
      
      #import "cCustomNavigationController.h"
      
      @interface cCustomNavigationController ()
      
      @end
      
      @implementation cCustomNavigationController 
      
      - (BOOL)shouldAutorotate {
          return [self.visibleViewController shouldAutorotate];
      }
      
      - (NSUInteger)supportedInterfaceOrientations {
          return [self.visibleViewController supportedInterfaceOrientations];
      }
      
      - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
          return [self.visibleViewController preferredInterfaceOrientationForPresentation];
      }
      
      @end
      
      //cCustomTabController.h file
      
      #import <UIKit/UIKit.h>
      
      @interface cCustomTabController : UITabBarController <UITabBarControllerDelegate>
      
      @end
      
      //cCustomTabController.m file
      
      #import "cCustomTabController.h"
      
      @interface cCustomTabController  ()
      
      @end
      
      @implementation cCustomTabController
      
      - (BOOL)shouldAutorotate {
          return [self.selectedViewController shouldAutorotate];
      }
      
      - (NSUInteger)supportedInterfaceOrientations {
          return [self.selectedViewController supportedInterfaceOrientations];
      }
      
      - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
          return [self.selectedViewController preferredInterfaceOrientationForPresentation];
      }
      
      @end
      

      现在您只需在需要的地方使用此类创建您的 TabBarControler 或 NavigationController,即

      //For the UINavigationController
      UINavigationController *navigationController = [[cCustomNavigationController alloc] init];
      
      //For the UITabBarController
      UITabBarController *tabController = [[cCustomTabController alloc] init];
      

      现在,您可以按照自己的方式控制所有视图的旋转,我正在使用它并且效果很好。

      我希望这对您有所帮助,但我不确定这是否正是您所需要的。

      编码愉快。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-30
        • 2011-12-17
        • 2010-11-03
        • 2021-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-15
        相关资源
        最近更新 更多