我有一个游戏,其中设备的方向会影响游戏的状态。用户必须在横向、纵向和反向横向方向之间快速切换。到目前为止,我一直在通过以下方式注册游戏以获取方向通知:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
但它太慢了——在转动手机和实际触发通知之间似乎有大约一秒钟的延迟。我需要一种方法来立即检测设备方向的变化。我尝试过使用陀螺仪进行试验,但对它还不够熟悉,无法知道它是否是我正在寻找的解决方案。
我有一个游戏,其中设备的方向会影响游戏的状态。用户必须在横向、纵向和反向横向方向之间快速切换。到目前为止,我一直在通过以下方式注册游戏以获取方向通知:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
但它太慢了——在转动手机和实际触发通知之间似乎有大约一秒钟的延迟。我需要一种方法来立即检测设备方向的变化。我尝试过使用陀螺仪进行试验,但对它还不够熟悉,无法知道它是否是我正在寻找的解决方案。
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];
}
我想这是你可以根据方向改变视图的最快速度
您所说的延迟实际上是防止错误(不需要的)方向更改通知的过滤器。
为了即时识别设备方向变化,您只需要自己监控加速度计。
加速度计测量所有 3 个轴的加速度(包括重力),因此您在确定实际方向时应该没有任何问题。
可以在此处找到一些开始使用加速度计的代码:
如何制作 iPhone 应用程序 - 第 5 部分:加速度计
这个不错的博客涵盖了数学部分:
为什么你不使用
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
?
或者你可以使用这个
-(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
或这个
-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
希望猫头鹰有用)
对于我的案件处理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");
}
}
尝试在以下方面进行更改:
- (void) viewWillLayoutSubviews {}
随着子视图再次布局,代码将在每次方向更改时运行。
@vimal 答案没有为我提供解决方案。似乎方向不是当前方向,而是来自先前的方向。为了修复它,我使用[[UIDevice currentDevice] orientation]
- (void)orientationChanged:(NSNotification *)notification{
[self adjustViewsForOrientation:[[UIDevice currentDevice] orientation]];
}
然后
- (void) adjustViewsForOrientation:(UIDeviceOrientation) orientation { ... }
使用此代码,我得到当前的方向位置。