在发布时检测界面方向的正确方法是什么?

时间:2010-11-21 18:28:05

标签: iphone ipad orientation

[问题更新]

所以这就是问题所在,我最终把它缩小到了这个范围。如果您在所有方法中创建一个新的UIViewController

- (id)init;
- (void)loadView;
- (void)viewDidAppear:(BOOL)animated;
- (void)viewDidLoad;
(...)

标准interfaceOrientation为Portrait,如果检测到横向模式,它将快速旋转到该方向。然后可以使用以下方法检测:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;

问题是在iPad上,在loadView(或其他一个)中为当前界面方向准备界面是很安静的,因为它只会返回Portrait。这会导致一些问题:

1)我希望我的内容在portait模式下重新加载,但不是在横向模式下。通常我会在loadView中放置一个if语句。如果处于纵向模式,请重新加载内容。但在这种情况下,它将始终返回纵向,因此始终加载内容。

2)我想使用'presentPopoverFromRect:inView:allowedArrowDirections:animated:' - 处于纵向模式的方法,以便在应用程序启动时自动显示弹出菜单。在纵向模式下启动时,这将使应用程序崩溃。原因:'弹出窗口无法从没有窗口的视图中显示。'。

唯一安全的假设是在'didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation'中,但如果它以纵向模式启动,则不会触发此方法。

// ----

更新(15.37)

'UIApplicationWillChangeStatusBarOrientationNotification'

仅在用户从纵向交换为横向(或反之亦然)时才会发布。如果接口是问题,那么通过观察该通知和

可以很容易地解决这个问题
if (UIDeviceOrientationIsPortrait(interfaceOrientation)) {
    // layout subviews for portrait mode
} else {
    // layout subviews for landscape mode
}

但问题是,我想知道它在启动时处于哪种模式以确定是否应该重新加载内容,我无法重新加载内容,当它切换到横向时取消它。

3 个答案:

答案 0 :(得分:8)

尝试[[UIApplication sharedApplication] statusBarOrientation]

答案 1 :(得分:6)

正确的方法是询问设备的方向,因为视图在技术上没有方向。 ;)

所以你使用UIDevice是正确的。从documentation您可以看到,在此信息正确之前,您首先需要生成设备方向通知。然后它将按照需要工作。

UIDevice *myDevice = [UIDevice currentDevice];
[myDevice beginGeneratingDeviceOrientationNotifications];
UIDeviceOrientation currentOrientation = [myDevice orientation];
[myDevice endGeneratingDeviceOrientationNotifications];

注意:这将为您提供设备的当前方向。如果当前可见/顶视图控制器允许旋转到此方向,您将获得当前设备方向,而不是最顶层视图控制器当前使用的方向。


问题更新后

编辑

您是正确的,最顶层视图控制器的方向(对于子视图控制器正常工作)始终在UIInterfaceOrientationPortrait中返回1(即loadView)。但是,方法willRotateToInterfaceOrientation:duration:将在之后立即被调用,并且在那里传递的方向是正确的,因此您应该能够使用该方法。

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toIfaceOrient
                                 duration:(NSTimeInterval)duration

答案 2 :(得分:1)

我不确定这是否能真正解决我的问题,但查看文档后我发现了以下内容:

typedef enum {
   UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,
   UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
   UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,
   UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft
} UIInterfaceOrientation;

typedef enum {
   UIDeviceOrientationUnknown,
   UIDeviceOrientationPortrait,
   UIDeviceOrientationPortraitUpsideDown,
   UIDeviceOrientationLandscapeLeft,
   UIDeviceOrientationLandscapeRight,
   UIDeviceOrientationFaceUp,
   UIDeviceOrientationFaceDown
} UIDeviceOrientation;

因为添加了FaceUp和FaceDown,因为接口原因,查看Device的方向是没有意义的。因此,从理论上讲,@ MarkAdams正确地提到在这种情况下[[UIApplication sharedApplication] statusBarOrientation]应该用于接口方向。

当然,UIViewController有'interfaceOrientation'选项。