How do I adjust CMMotionManager data for orientation under iOS 8?

前端 未结 2 1706
生来不讨喜
生来不讨喜 2021-01-25 02:49

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

相关标签:
2条回答
  • 2021-01-25 02:58

    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;
    }
    
    0 讨论(0)
  • 2021-01-25 03:06

    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.

    0 讨论(0)
提交回复
热议问题