54

我有一个游戏,其中设备的方向会影响游戏的状态。用户必须在横向、纵向和反向横向方向之间快速切换。到目前为止,我一直在通过以下方式注册游戏以获取方向通知:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

但它太慢了——在转动手机和实际触发通知之间似乎有大约一秒钟的延迟。我需要一种方法来立即检测设备方向的变化。我尝试过使用陀螺仪进行试验,但对它还不够熟悉,无法知道它是否是我正在寻找的解决方案。

4

6 回答 6

144

viewWillAppear在函数中添加通知器

-(void)viewWillAppear:(BOOL)animated{
  [super viewWillAppear:animated];
  [[NSNotificationCenter defaultCenter] addObserver:self  selector:@selector(orientationChanged:)    name:UIDeviceOrientationDidChangeNotification  object:nil];
}

方向变化通知此功能

- (void)orientationChanged:(NSNotification *)notification{
   [self adjustViewsForOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
}

依次调用此函数,其中处理moviePlayerController框架的方向

- (void) adjustViewsForOrientation:(UIInterfaceOrientation) orientation {

    switch (orientation)
    {
        case UIInterfaceOrientationPortrait:
        case UIInterfaceOrientationPortraitUpsideDown:
        { 
        //load the portrait view    
        }

            break;
        case UIInterfaceOrientationLandscapeLeft:
        case UIInterfaceOrientationLandscapeRight:
        {
        //load the landscape view 
        }
            break;
        case UIInterfaceOrientationUnknown:break;
    }
}

viewDidDisappear删除通知

-(void)viewDidDisappear:(BOOL)animated{
   [super viewDidDisappear:animated];
   [[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
}

我想这是你可以根据方向改变视图的最快速度

于 2012-08-23T07:09:31.070 回答
25

您所说的延迟实际上是防止错误(不需要的)方向更改通知的过滤器。

为了即时识别设备方向变化,您只需要自己监控加速度计。

加速度计测量所有 3 个轴的加速度(包括重力),因此您在确定实际方向时应该没有任何问题。

可以在此处找到一些开始使用加速度计的代码:

如何制作 iPhone 应用程序 - 第 5 部分:加速度计

这个不错的博客涵盖了数学部分:

使用加速度计

于 2012-08-23T07:06:47.247 回答
21

为什么你不使用

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

?

或者你可以使用这个

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

或这个

-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation

希望猫头鹰有用)

于 2012-08-23T06:53:20.707 回答
12

对于我的案件处理UIDeviceOrientationDidChangeNotification不是很好的解决方案,因为它被称为更频繁并且UIDeviceOrientation并不总是等于UIInterfaceOrientation因为(FaceDown,FaceUp)。

我处理它使用UIApplicationDidChangeStatusBarOrientationNotification

//To add the notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeOrientation:)

//to remove the
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];

 ...

- (void)didChangeOrientation:(NSNotification *)notification
{
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;

    if (UIInterfaceOrientationIsLandscape(orientation)) {
        NSLog(@"Landscape");
    }
    else {
        NSLog(@"Portrait");
    }
}
于 2014-12-23T08:26:52.450 回答
5

尝试在以下方面进行更改:

- (void) viewWillLayoutSubviews {}

随着子视图再次布局,代码将在每次方向更改时运行。

于 2013-03-25T19:36:56.033 回答
5

@vimal 答案没有为我提供解决方案。似乎方向不是当前方向,而是来自先前的方向。为了修复它,我使用[[UIDevice currentDevice] orientation]

- (void)orientationChanged:(NSNotification *)notification{
    [self adjustViewsForOrientation:[[UIDevice currentDevice] orientation]];
}

然后

- (void) adjustViewsForOrientation:(UIDeviceOrientation) orientation { ... }

使用此代码,我得到当前的方向位置。

于 2014-02-10T09:57:06.553 回答