I am using the UIAccelerotmeterDelegate method accelerometer:didAccelerate: but recently that method has been deprecated in iOS 5.0. So what is the alternative way to get the accelerometer data? The documentation does not mention the alternative we are supposed to use.

有帮助吗?

解决方案

You should use the Core Motion framework (introduced in iOS 4.0) as a substitue. Create an instance of CMMotionManager and tell it to startAccelerometerUpdatesToQueue:withHandler:, passing it an NSOperationQueue and a block that will be executed on the specified queue whenever new accelerometer data is available.

其他提示

It seems that UIAccelerometer and UIAccelerometerDelegate were replaced by the CoreMotion framework.

You can find the answer here:

Why is accelerometer:didAccelerate: deprecated in IOS5?

I Hope it helps.

Here is a useful sample code I found for CoreMotion from this link.

    @interface ViewController ()

    @property (nonatomic, strong) CMMotionManager *motionManager; 
    @property (nonatomic, strong) IBOutlet UILabel *xAxis; 
    @property (nonatomic, strong) IBOutlet UILabel *yAxis; 
    @property (nonatomic, strong) IBOutlet UILabel *zAxis; 

    @end

    @implementation ViewController
    - (void)viewDidLoad 
    { 
      [super viewDidLoad];

      self.motionManager = [[CMMotionManager alloc] init]; 
      self.motionManager.accelerometerUpdateInterval = 1;

      if ([self.motionManager isAccelerometerAvailable]) 
      { 
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        [self.motionManager startAccelerometerUpdatesToQueue:queue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
            dispatch_async(dispatch_get_main_queue(), ^{ 
              self.xAxis.text = [NSString stringWithFormat:@"%.2f",accelerometerData.acceleration.x]; 
              self.yAxis.text = [NSString stringWithFormat:@"%.2f",accelerometerData.acceleration.y]; 
              self.zAxis.text = [NSString stringWithFormat:@"%.2f",accelerometerData.acceleration.z];
            });
          }]; 
      } else 
      NSLog(@"not active"); 
    }
@end

Its replaced by CoreMotion. See Motion Events.

Add CoreMotion framework to the project first. Then:

#import <CoreMotion/CoreMotion.h>

@property (strong, nonatomic) CMMotionManager *motionManager;

- (void)viewDidLoad {
    _motionManager = [CMMotionManager new];
    _motionManager.accelerometerUpdateInterval = 0.01;       // 0.01 = 1s/100 = 100Hz
    if ([_motionManager isAccelerometerAvailable])
    {
        NSOperationQueue *queue = [NSOperationQueue new];
        [_motionManager startAccelerometerUpdatesToQueue:queue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error){
             NSLog(@"X = %0.4f, Y = %.04f, Z = %.04f",
                   accelerometerData.acceleration.x,
                   accelerometerData.acceleration.y,
                   accelerometerData.acceleration.z);
         }];
    }
}

I am answering this for Swift 5.x.

@available(iOS, introduced: 2.0, deprecated: 13.0, message: "UIAcceleration has been replaced by the CoreMotion framework") public protocol UIAccelerometerDelegate : NSObjectProtocol { }

Add CoreMotion framework only. Don't conform to UIAccelerometerDelegate.

import CoreMotion

If you want to show animation or create a game, you can start with the following code.

self.motionManager = CMMotionManager()
self.motionManager?.startAccelerometerUpdates()
if motionManager.isAccelerometerAvailable {          
  motionManager.startAccelerometerUpdates(to: .main) { (data, error) in
    if let myData = data {
        let x =  String(format: "%.3f",myData.acceleration.x)
        let y =  String(format: "%.3f",myData.acceleration.y)
        let z =  String(format: "%.3f",myData.acceleration.z)
    DispatchQueue.main.async { 
          var rect = self.anyObject.frame
         let movetoX = rect.origin.x + CGFloat(myData.acceleration.x * stepMoveFactor)
         let movetoY = rect.origin.y - CGFloat(myData.acceleration.y * stepMoveFactor)
         if ( movetoX > 0 && movetoX < SCREEN_WIDTH ) {
            rect.origin.x += CGFloat(myData.acceleration.x * stepMoveFactor)
         }
         if ( movetoY > 1 && movetoY < maxY ) {
           rect.origin.y -= CGFloat(myData.acceleration.y * stepMoveFactor) }
         }
    }
  }
}

use UIView.animate if you want. This method initiates a set of animations to perform on the view. The block object in the animations parameter contains the code for animating the properties of one or more views.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top