如何在iOS 8下调整CMMotionManager数据的方向?

我的应用程序使用CMMotionManager来跟踪设备运动,但是iOS始终以标准设备方向(底部的主页button)返回设备运动数据。

为了将运动数据转换为与我的UIView相同的方向,我从我的视图中累积了视图变换,如下所示:

CGAffineTransform transform = self.view.transform; for (UIView *superview = self.view.superview; superview; superview = superview.superview) { CGAffineTransform superviewTransform = superview.transform; transform = CGAffineTransformConcat(transform, superviewTransform); } 

这个变换在iOS 6和7下得到了正确的计算,但是iOS 8改变了旋转模型,现在视图总是返回标识变换(不旋转),不pipe设备如何定向。 尽pipe如此,来自运动pipe理器的数据仍然以标准方向固定。

监控UIDevice旋转通知和手动计算四个转换似乎是在iOS 8下获得此转换的一种方法,但它也似乎不好,因为设备的方向不一定匹配我的视图的方向(即,iPhone上的方向不是设备方向通常支持)。

将CMMotionManager的输出转化为iOS 8下特定UIView的方向的最好方法是什么?

虽然不是很明显,但在iOS 8及更高版本中推荐的方法是使用过渡协调器。

viewWillTransition(to:with:) ,协调器可以传递一个采用UIViewControllerTransitionCoordinatorContext的实例在你调用的任何方法的完成块中(UIKit使用的默认协调器实际上是它自己的上下文,但这不一定是这种情况)。

上下文的targetTransform属性是在animation结束时应用到接口的旋转。 注意这是一个相对变换,而不是接口产生的绝对变换。

 override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) let animation: (UIViewControllerTransitionCoordinatorContext) -> Void = { context in // your animation } coordinator.animate(alongsideTransition: animation) { context in // store the relative rotation (or whatever you need to do with it) self.transform = context.targetTransform } } 

虽然旧的方法仍然有效,但这个API大概更符合苹果UI框架的未来发展方向,而且当你需要控制animation转换的时候,它的确具有更大的灵活性。

我无法find直接计算转换的方法,所以相反,我改变了我的代码来计算在我的视图控制器中接收到willRotateToInterfaceOrientation:消息时手动设置转换,如下所示:

 - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { CGAffineTransform transform; switch (toInterfaceOrientation) { case UIInterfaceOrientationLandscapeLeft: transform = CGAffineTransformMake( 0, -1, 1, 0, 0, 0); break; case UIInterfaceOrientationLandscapeRight: transform = CGAffineTransformMake( 0, 1, -1, 0, 0, 0); break; case UIInterfaceOrientationPortraitUpsideDown: transform = CGAffineTransformMake( -1, 0, 0, -1, 0, 0); break; case UIInterfaceOrientationPortrait: transform = CGAffineTransformIdentity; break; } self.motionTransform = transform; }