立即检测iOS方向的变化

时间:2012-08-23 06:33:32

标签: iphone objective-c ios orientation gyroscope

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

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

但它太慢了 - 旋转手机和实际被解雇的通知之间似乎有大约第二个延迟。我需要一种方法来立即检测设备方向的变化。我已经尝试过使用陀螺仪进行试验,但我还不熟悉它,知道它是否是我正在寻找的解决方案。

6 个答案:

答案 0 :(得分:143)

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];
}

我想这是最快你可以根据方向更改视图

答案 1 :(得分:23)

您正在谈论的延迟实际上是一个过滤器,可以防止错误(不需要的)方向更改通知。

对于即时识别设备方向更改,您只需要自己监控加速度计。

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

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

How to make an iPhone App – Part 5: The Accelerometer

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

Using the Accelerometer

答案 2 :(得分:21)

为什么你没有使用

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

或者你可以使用这个

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

或者这个

-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation

希望它有用)

答案 3 :(得分:11)

对于我的案例处理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");
    }
}

答案 4 :(得分:5)

尝试进行更改:

- (void) viewWillLayoutSubviews {}

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

答案 5 :(得分:5)

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

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

然后

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

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