Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 即时检测iOS方向变化_Iphone_Objective C_Ios_Orientation_Gyroscope - Fatal编程技术网

Iphone 即时检测iOS方向变化

Iphone 即时检测iOS方向变化,iphone,objective-c,ios,orientation,gyroscope,Iphone,Objective C,Ios,Orientation,Gyroscope,我有一个游戏,其中设备的方向会影响游戏的状态。用户必须在横向、纵向和反向横向方向之间快速切换。到目前为止,我一直在通过以下方式注册游戏以获取定向通知: [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 但是它太慢了——在旋转手机和实际发出通知之间似乎有一秒的延迟。我需要一种方法来即时检测设备方向的变化。我尝试过使用陀螺仪,但对它还不够熟悉,不知道它是否是我正在寻找的解决方案。为什么不使用陀螺仪 -

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

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
但是它太慢了——在旋转手机和实际发出通知之间似乎有一秒的延迟。我需要一种方法来即时检测设备方向的变化。我尝试过使用陀螺仪,但对它还不够熟悉,不知道它是否是我正在寻找的解决方案。

为什么不使用陀螺仪

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
?

或者你可以用这个

-(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
还是这个

-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
希望它有用)

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

对于即时识别设备方向变化,您只需自己监控加速计即可

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

以下是一些开始使用加速计的代码:

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


视图中添加通知程序将出现
功能

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

在<代码>视图中删除通知

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


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

尝试在以下位置进行更改:

-(void)视图将布局子视图{}


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

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

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


使用此代码,我得到了当前的定位。

对于我的案例处理,
UIDeviceOrientationIDChangeNotification
不是一个好的解决方案,因为它被称为更频繁的定位,并且由于(面朝下,面朝上)的原因,
UIDeviceOrientation
并不总是等于
UIInterfaceOrientation

我使用
UIApplicationIDChangeStatusBarOrientationNotification
处理它:

//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");
    }
}

给你,用这个。如果有任何疑问,请告诉我。非常好的文章这些方法不会在子视图控制器上自动调用。这些方法现在已弃用。UIAccelerator已弃用并由Core MotionSecond链接替换。请不要忘记[super ViewWillDisplay:animated]和[super ViewDidDemoved:animated]在复制粘贴的情况下,就像真正的程序员一样。注意:UIDeviceOrientation!=界面定向。
//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");
    }
}