立即检测 iOS 方向变化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12085990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detecting iOS orientation change instantly
提问by GoldenJoe
I have a game in which the orientation of the device affects the state of the game. The user must quickly switch between Landscape, Portrait, and Reverse Landscape orientations. So far I've been registering the game for orientation notifications via:
我有一个游戏,其中设备的方向会影响游戏的状态。用户必须在横向、纵向和反向横向方向之间快速切换。到目前为止,我一直在通过以下方式注册游戏以获取方向通知:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
But it is far too slow - there seems to be about a second delay between rotating the phone and the notification actually being fired. I need a way to INSTANTLY detect changes in the device's orientation. I have tried experimenting with the gyroscope, but am not yet familiar enough with it to know whether or not it is the solution I am looking for.
但它太慢了 - 在旋转手机和实际触发通知之间似乎有第二次延迟。我需要一种方法来即时检测设备方向的变化。我尝试过使用陀螺仪进行试验,但对它还不够熟悉,无法知道它是否是我正在寻找的解决方案。
采纳答案by Rok Jarc
That delayyou're talking about is actually a filter to prevent false (unwanted) orientation change notifications.
这延迟你所谈论的实际上是一个过滤器,以防止错误的(不必要的)方向变化的通知。
For instantrecognition of device orientation change you're just gonna have to monitor the accelerometer yourself.
为了即时识别设备方向的变化,您只需要自己监控加速度计。
Accelerometer measures acceleration (gravity included) in all 3 axes so you shouldn't have any problems in figuring out the actual orientation.
加速度计测量所有 3 个轴的加速度(包括重力),因此您在确定实际方向时应该没有任何问题。
Some code to start working with accelerometer can be found here:
可以在此处找到一些开始使用加速度计的代码:
How to make an iPhone App – Part 5: The Accelerometer
And this nice blog covers the math part:
这个不错的博客涵盖了数学部分:
回答by Vimal Venugopalan
Add a notifier in the viewWillAppear
function
在viewWillAppear
函数中添加通知程序
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
}
The orientation change notifies this function
方向改变通知这个函数
- (void)orientationChanged:(NSNotification *)notification{
[self adjustViewsForOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
}
which in-turn calls this function where the moviePlayerController frame is orientation is handled
依次调用此函数,其中处理 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;
}
}
in viewDidDisappear
remove the notification
在viewDidDisappear
删除通知
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
}
I guess this is the fastest u can have changed the view as per orientation
我想这是u能已经改变了看法按方位最快
回答by Arthur
Why you didn`t use
为什么你没有使用
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
?
?
Or you can use this
或者你可以使用这个
-(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
Or this
或这个
-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
Hope it owl be useful )
希望猫头鹰有用)
回答by B.S.
For my case handling UIDeviceOrientationDidChangeNotification
was not good solution as it is called more frequent and UIDeviceOrientation
is not always equal to UIInterfaceOrientation
because of (FaceDown, FaceUp).
对于我的案例处理UIDeviceOrientationDidChangeNotification
不是一个好的解决方案,因为它被称为更频繁并且UIDeviceOrientation
并不总是等于UIInterfaceOrientation
(FaceDown,FaceUp)。
I handle it using UIApplicationDidChangeStatusBarOrientationNotification
:
我处理它使用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");
}
}
回答by powerj1984
Try making your changes in:
尝试在以下方面进行更改:
- (void) viewWillLayoutSubviews {}
- (void) viewWillLayoutSubviews {}
The code will run at every orientation change as the subviews get laid out again.
随着子视图再次布局,代码将在每次方向更改时运行。
回答by Dody Rachmat Wicaksono
@vimal answer did not provide solution for me. It seems the orientation is not the current orientation, but from previous orientation. To fix it, I use [[UIDevice currentDevice] orientation]
@vimal 的回答没有为我提供解决方案。似乎方向不是当前的方向,而是来自先前的方向。要修复它,我使用[[UIDevice currentDevice] orientation]
- (void)orientationChanged:(NSNotification *)notification{
[self adjustViewsForOrientation:[[UIDevice currentDevice] orientation]];
}
Then
然后
- (void) adjustViewsForOrientation:(UIDeviceOrientation) orientation { ... }
With this code I get the current orientation position.
使用此代码,我可以获得当前的方向位置。