在我的程序中,我根据旋转移动东西,但我没有旋转整个视图。我正在使用:
static UIDeviceOrientation previousOrientation = UIDeviceOrientationPortrait;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:viewController.view];
[window makeKeyAndVisible];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didRotate:)
name:@"UIDeviceOrientationDidChangeNotification" object:nil];
}
- (void) didRotate:(NSNotification *)notification{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
[self doRotationStuff:orientation: previousOrientation];
previousOrientation = orientation;
}
只要程序启动时,设备方向为纵向,但如果初始方向是横向或颠倒,则无效,因为[self doRotationStuff]相对于与前一个方向的差异进行更改。< / p>
有没有办法在发布时或在设备旋转之前检测方向?
答案 0 :(得分:12)
根据您的具体情况,更简单的选项可能是UIViewController类的interfaceOrientation属性。在轮换之前这是正确的。
答案 1 :(得分:3)
<强>更新强>
因此,从评论讨论中看来,在第一次实际更改方向之前,您不能依赖[UIDevice currentDevice].orientation
。如果是这样,你可能会通过获取原始加速度计读数来破解它。
#define kUpdateFrequency 30 // Hz
#define kUpdateCount 15 // So we init after half a second
#define kFilteringFactor (1.0f / kUpdateCount)
- (void)applicationDidFinishLaunching:(UIApplication *)app
{
[UIAccelerometer sharedAccelerometer].updateInterval = (1.0 / kUpdateFrequency);
[UIAccelerometer sharedAccelerometer].delegate = self;
accelerometerCounter = 0;
...
}
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)accel
{
// Average out the first kUpdateCount readings
// acceleration_[xyz] are ivars typed float
acceleration_x = (float)accel.x * kFilteringFactor + acceleration_x * (1.0f - kFilteringFactor);
acceleration_y = (float)accel.y * kFilteringFactor + acceleration_y * (1.0f - kFilteringFactor);
acceleration_z = (float)accel.z * kFilteringFactor + acceleration_z * (1.0f - kFilteringFactor);
accelerometerCounter++;
if (accelerometerCounter == kUpdateCount)
{
[self initOrientation];
[UIAccelerometer sharedAccelerometer].delegate = nil;
}
}
- (void)initOrientation
{
// Figure out orientation from acceleration_[xyz] and set up your UI...
}
原始回复:
[UIDevice currentDevice].orientation
期间applicationDidFinishLaunching:
会返回正确的方向吗?如果是这样,您可以根据该方向设置初始UI。
如果该属性直到稍后才设置,您可能会尝试使用performSelector:afterDelay:
在稍微延迟后初始化UI。
此代码示例来自Kendall的答案,此处为了完整性而添加:
[self performSelector:@selector(getOriented) withObject:nil afterDelay:0.0f];
我不确定零秒延迟是否足够 - 这意味着getOriented
的代码将在第一次通过事件运行循环期间运行。您可能需要等待更长时间才能在UIDevice
上注册加速度计读数。
答案 2 :(得分:1)
莫尔,这些答案似乎有点像红鲱鱼;我不明白为什么你不能为UIViewController类使用以下内置方法:
-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {}
在旋转发生后自动调用此方法(而不是使用shouldAutorotateToInterfaceOrientation,它只会告诉您即将发生)。方便地,变量'fromInterfaceOrientation'包含先前的方向。正如文档中所述,您可以假设视图的interfaceOrientation属性已经设置为新方向,因此您可以使用一个方法来访问旧方向和新方向!
如果我错过了某些内容并且您已经解雇了能够使用此方法的话,我很抱歉!在上述方法中免费提供变量时,您正在为“之前的方向”创建和存储变量,这似乎很奇怪。
希望有所帮助!
答案 3 :(得分:1)
如果您需要确定指向的方式,请将其用于UI的方向。
不是100%肯定这是正确的,但是我不知道如何:
[[[UIApplication sharedApplication] statusBar] orientation]
答案 4 :(得分:1)
这是在应用程序首次加载且UIDeviceOrientation设置为UIDeviceOrientationUnknown时获取方向的一种方法。您可以查看旋转视图的transform属性。
if(toInterface == UIDeviceOrientationUnknown) {
CGAffineTransform trans = navigationController.view.transform;
if(trans.b == 1 && trans.c == -1)
toInterface = UIDeviceOrientationLandscapeLeft;
else if(trans.b == -1 && trans.c == 1)
toInterface = UIDeviceOrientationLandscapeRight;
else if(trans.a == -1 && trans.d == -1)
toInterface = UIDeviceOrientationPortraitUpsideDown;
else
toInterface = UIDeviceOrientationPortrait;
}
答案 5 :(得分:0)
可以找到有关如何从加速器读数获取设备方向的更完整示例here 由于解决方案依赖于加速器读数,因此无法在模拟器上运行,因此您必须在设备上工作......仍然在寻找可在模拟器上运行的解决方案。
答案 6 :(得分:-1)
在回复你的评论时,我认为我最好把代码放在这里而不是评论中(虽然丹尼尔值得赞扬):
在applicationDidFinishLaunching中:
[self performSelector:@selector(getOriented) withObject:nil afterDelay:0.0f];
然后你只需要调用方法:
- (void) getOriented
{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
// save orientation somewhere
}