My application uses CMMotionManager to track device motion, but iOS always returns device motion data in the standard device orientation (home button at the bottom).
To
I couldn't find a way to directly calculate the transform, so instead I changed my code to calculate set the transform manually when a willRotateToInterfaceOrientation: message is received in my view controller, like this:
- (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;
}
Although not very obvious, the recommended way of doing this in iOS 8 and later is with transition coordinators.
In viewWillTransition(to:with:)
, the coordinator can pass you an object adopting UIViewControllerTransitionCoordinatorContext
in the completion blocks of whichever of its methods you call (the default coordinator used by UIKit is actually its own context, but this isn't necessarily the case).
The context's targetTransform
property is the rotation to be applied to the interface by the end of the animation. Note this is a relative transform, not the resulting absolute transform of the interface.
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
let animation: (UIViewControllerTransitionCoordinatorContext) -> Void = { context in
// Update animatable properties.
}
coordinator.animate(alongsideTransition: animation) { context in
// Store or use the transform.
self.mostRecentTransform = context.targetTransform
}
}
While the old approach still works, this API is a bit more flexible when you need to coordinate animated transitions, such as when working with graphics frameworks or using a custom layout.