查看旋转通知:为什么didRotateFromInterfaceOrientation:方法没有被调用?

13

我试图检测任何设备方向的改变,以便更新视图。

我想在横屏或竖屏模式下均更新视图,因此我实现了以下方法:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

我知道如果要更新视图以正确显示当前方向,我需要实现以下方法之一:

 willRotateToInterfaceOrientation:duration:
 willAnimateRotationToInterfaceOrientation:duration:
 didRotateFromInterfaceOrientation:
 willAnimateFirstHalfOfRotationToInterfaceOrientation:duration:
 didAnimateFirstHalfOfRotationToInterfaceOrientation:
 willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:

现在的问题是,我不明白为什么当我旋转模拟器时,这些方法都没有被触发。

我也尝试了这段代码:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

但仍然没有任何反应。所以我想知道,模拟器是否会发出旋转通知?如果是,那我做错了什么?


你在哪里实现了这个方法? - Deepak Danduprolu
是的,模拟器会发送旋转通知。 - Ishu
@Ishu:谢谢你提供的信息;@Deepak:如果你指的是didRotateFromInterfaceOrientation方法,我已经在我的视图控制器的.m文件中实现了它;如果你说的是[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications],我已经在视图控制器的viewDidLoad中实现了它。 - Francesco Puglisi
2个回答

53

你需要添加通知观察器,类似于以下内容:

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

并添加该方法

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

       if (orientation == UIDeviceOrientationLandscapeLeft)
      {
        NSLog(@"Landscape Left!");
      }
}

4
谢谢,这正是我所需要的 - 看起来普遍建议使用[UIApplication sharedApplication].statusBarOrientation比UIDevice orientation更可靠,因此人们可能想要使用前者 - 我肯定会这样做。 - JosephH
请注意,在上面的代码中,UIDeviceOrientationDidChangeNotification 应该是一个常量,而不是实际值。只是恰好常量的值是 UIDeviceOrientationDidChangeNotification :-) - Ben Gotow
1
关于statusBarOrientation和currentDevice orientation,我的一些快速测试表明,在这种情况下检查statusBarOrientation实际上返回之前的方向,而currentDevice返回当前/新方向。此外,CurrentDevice将包括UIDeviceOrientationFaceUp和UIDeviceOrientationFaceDown,而statusBar从未包含它们。 - orion elenzil

5

简要概述:将此更改为:

[window addSubview:viewController.view];

转换为:

[window setRootViewController:viewController];

如果我因为一个愚蠢的错误占用了某人的时间,我很抱歉。我找到了为什么方法– willRotateToInterfaceOrientation:duration:永远不会被调用的原因。有些事情引起了我对导航控制器的注意:

只有根视图控制器的willRotate方法被调用。很可能你有一个奇怪的视图控制器层次结构。

我在另一个论坛上找到了这些帖子,并查看了应用程序委托。我的代码如下:

CGRect bound = [[UIScreen mainScreen] bounds];
window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, bound.size.width, bound.size.height)];
TestViewController *viewController = [[TestViewController alloc] init];
[window addSubview:viewController.view];
[viewController release];
[self.window makeKeyAndVisible];

问题在于我没有为窗口设置任何视图控制器,而只是添加了一个视图。这是我因急于测试某些内容而犯的错误。我必须将代码修复如下:
CGRect bound = [[UIScreen mainScreen] bounds];
window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, bound.size.width, bound.size.height)];
TestViewController *viewController = [[TestViewController alloc] init];
[window setRootViewController:viewController];
[viewController release];
[self.window makeKeyAndVisible];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接