7

我的应用程序有大约 10 个不同的 UIViewControllers,如果设备旋转,我只想将其中一个切换到横向模式。(其余的,我想保持肖像。)

为了在那个视图上实现旋转,我需要实现其控制器的“shouldAutorotate”方法并返回 YES。由于此视图是通过导航控制器访问的,因此我还需要创建 UINavigationController 的子类,该子类实现“shouldAutorotate”并返回 YES。

此解决方案有效,但效果很好。我发现我推送到我的 UINavigationController 子类上的所有 UIViewController 都会响应旋转,即使我实现了“shouldAutorotate”并返回 NO。(请记住:我只希望一个特定的 UIViewController 响应旋转,而不是导航控制器堆栈中的每个。)

所以,我的问题是:我怎样才能最好地做到这一点?我能想出的所有解决方案似乎 1) 很麻烦,2) 更糟糕的是,似乎不起作用。

非常感谢。

4

4 回答 4

2

当您实现 UINavigationController 时,此类是您的父级,它控制将被推入堆栈的所有子视图控制器。因此,RootViewController 是唯一对自动旋转说“是”或“否”的控制器。即使您将 Yes 传递给子视图控制器中的自动旋转,它们也不算数!

这就是 UINavigationController 的本质。所以要改变它,你有两个选择:

1-手动操作它,这需要您通过一些繁琐的代码。

2-更改您的设计,使其与 UINavigationController 更兼容。应该旋转的单个视图应该由承载 NavController 的视图 RootViewController(不是导航根视图控制器——它们的名称相同,但完全不同)调用。当设备旋转时,它会将 NavController 推送到视图或另一个。

3- 另一种方法也可以,但不推荐,因为它违反了 MVC 的概念,是你的 NavController 可以监听通知。那个可以并且应该旋转的特定子视图可以发出一个通知——例如rotateMe,一旦NavController听到它,它就会旋转。

正如我所说,它会起作用,但它违反了 MVC 模型——这对 Apple 来说很好,但从编程的角度来看不推荐。

如果您需要关于其中任何一个的进一步解释,请告诉我。

于 2011-10-01T16:39:13.450 回答
1

仅当 [[navController topViewController] isKindOfClass:[RotatingViewController class]] 时在导航控制器子类上返回 YES

于 2011-09-01T17:29:12.790 回答
1

我通过拥有一个根视图控制器(这可能是一个 UITabBarController)并在它的 viewDidLoad 方法中订阅旋转事件来做到这一点:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(didRotate:)
                                                      name:@"UIDeviceOrientationDidChangeNotification" 
                                                      object:nil];

然后在 didRotate: 方法中,我查看旋转发生时哪个视图控制器可见,以及手机的方向:

- (void) didRotate:(NSNotification *)notification { 
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

/*
    DEVICE JUST ROTATED TO PORTRAIT MODE

 orientation == UIDeviceOrientationFaceUp ||
 orientation == UIDeviceOrientationFaceDown

 */
if(orientation == UIDeviceOrientationPortrait) {





/*
    DEVICE JUST ROTATED TO LANDSCAPE MODE
 */
}else if(orientation == UIInterfaceOrientationLandscapeLeft ||
        orientation == UIInterfaceOrientationLandscapeRight) {






}

}

在那个 didRotate: 中,您可以查看哪个是可见的 viewController 并从那里做您想做的事情。

当特定视图控制器可见并且手机旋转为横向时,我会在横向模式下呈现模态视图控制器。如果任何其他视图控制器可见,我将忽略该事件。

我强制我的模态视图控制器在其 viewWillAppear 方法中以横向模式显示 - 如果他们想要,我可以给任何人这个代码。

希望这可以帮助。

戴夫

于 2010-06-28T15:30:27.167 回答
0

我已经看到使用您正在执行的方式的示例,但无法使其正常工作。我从 Apple 的示例中找到了更好的方法。基本上你实现了一个 presentModalViewController 并创建另一个视图。UIKit 做了一个基本的旋转动画并在视图之间淡入淡出。您必须将旋转视图实现为委托类,以便它可以回调其调用类以将其关闭并更新方向。

- (void)orientationChanged:(NSNotification *)notification
{
    // We must add a delay here, otherwise we'll swap in the new view
    // too quickly and we'll get an animation glitch
    NSLog(@"orientationChanged");
    [self performSelector:@selector(updateLandscapeView) withObject:nil afterDelay:0];
}

然后显示一个横向屏幕:

- (void)updateLandscapeView
{
PortraitView *portraitView = [[PortraitView alloc] init];
portraitView.delegate = self;
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !isShowingLandscapeView)
{
    [self presentModalViewController: portraitView animated:YES];
    isShowingLandscapeView = YES;
    }
else if (deviceOrientation == UIDeviceOrientationPortrait && isShowingLandscapeView)
{
    [self dismissModalViewControllerAnimated:YES];
    isShowingLandscapeView = NO;
    }
[portraitView release];
}
于 2010-05-15T05:31:56.440 回答