昨天写了重力感应的例子,我觉得这个例子比较有用处,我分享出来:
1 )显然ios4 之后可以使用coreMotion的framework 为了向下兼容加上UIAccelerator,
#import <Foundation/Foundation.h> #import <CoreMotion/CoreMotion.h> @protocol IFAccelerometerDelegate<NSObject> - (void)accelerateWithX:(NSNumber*)x withY:(NSNumber*)y withZ:(NSNumber*)z withTimeInterval:(NSTimeInterval)timeInterval; @end @interface IFAccelerometer : NSObject<UIAccelerometerDelegate> { UIAccelerometer *_accelerometer; CMMotionManager *_motionManager; id<IFAccelerometerDelegate> _delegate; } + (id)shareAccelerometer; - (void)addOberser:(id)oberserer; - (void)removeObserver; @end
同时,咱们不能在需要监测重力感应的地方直接使用这个类,这样耦合比较严重,也不利于重用。所以抽离出来,在代码中您可以看到,我将定义一个signleton,同时将重力变化的事件回调给其代理。
2.接着往下是定义其函数,这个很简单,直接贴代码。
#import "IFAccelerometer.h" static IFAccelerometer *accelerometerInstance = nil; @implementation IFAccelerometer + (id)shareAccelerometer { if (!accelerometerInstance) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ accelerometerInstance = [[[self class]alloc]init]; }); } return accelerometerInstance; } - (id)init { self = [super init]; if (self) { #ifdef __IPHONE_5_0 _motionManager = [[CMMotionManager alloc]init]; if (_motionManager.accelerometerAvailable) { [_motionManager setAccelerometerUpdateInterval:1/60.f]; NSOperationQueue *operationQueue = [NSOperationQueue mainQueue]; [_motionManager startAccelerometerUpdatesToQueue:operationQueue withHandler:^(CMAccelerometerData *data,NSError *error) { if ([_delegate respondsToSelector:@selector(accelerateWithX:withY:withZ:withTimeInterval:)]) { NSNumber *x = [NSNumber numberWithDouble:data.acceleration.x]; NSNumber *y = [NSNumber numberWithDouble:data.acceleration.y]; NSNumber *z = [NSNumber numberWithDouble:data.acceleration.z]; [_delegate accelerateWithX:x withY:y withZ:z withTimeInterval:data.timestamp]; } } ]; } #else #ifdef __IPHONE_4_0 _accelerometer = [UIAccelerometer sharedAccelerometer]; [_accelerometer setUpdateInterval:(1/60.0f)]; _accelerometer.delegate = self; #endif #endif } return self; } - (void)addOberser:(id)oberserer { _delegate = oberserer; } - (void)removeObserver { _delegate = nil; } - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { if ([_delegate respondsToSelector:@selector(accelerateWithX:withY:withZ:withTimeInterval:)]) { NSNumber *x = [NSNumber numberWithDouble:acceleration.x]; NSNumber *y = [NSNumber numberWithDouble:acceleration.y]; NSNumber *z = [NSNumber numberWithDouble:acceleration.z]; [_delegate accelerateWithX:x withY:y withZ:z withTimeInterval:acceleration.timestamp]; } }3.以ViewController 为例介绍如何使用重力感应
- (void)viewDidLoad { [super viewDidLoad]; [[IFAccelerometer shareAccelerometer]addOberser:self]; _imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"33.png"]]; _imageView.frame = CGRectMake(0, 0, KIMAGEWIDTH, KIMAGEHEIGHT); _imageView.center = self.view.center; [self.view addSubview:_imageView]; }
注意,我在头文件添加了重力感应的代理,此时这行
[[IFAccelerometer shareAccelerometer]addOberser:self];
表明我在这个viewController中使用这个重力感应的数据。
好,现在是完成回调的时候了,继续贴代码
- (void)accelerateWithX:(NSNumber *)x withY:(NSNumber *)y withZ:(NSNumber *)z withTimeInterval:(NSTimeInterval)timeInterval { float deceleration = 0.4f; float sensitivity = 6.0f; float maxVelocity = 100.0f; velocity.x = velocity.x * deceleration + [x doubleValue] * sensitivity; velocity.y = velocity.y * deceleration + [y doubleValue] * sensitivity; if(velocity.x > maxVelocity){ velocity.x = maxVelocity; }else if(velocity.x < -maxVelocity){ velocity.x = -maxVelocity; } if(velocity.y > maxVelocity){ velocity.y = maxVelocity; }else if(velocity.y < -maxVelocity){ velocity.y = -maxVelocity; } CGPoint pos = _imageView.center; pos.x += velocity.x; pos.y -= velocity.y; float imageWidthHalved = KIMAGEWIDTH * 0.5f; float leftBorderLimit = 0.0f; float rightBorderLimit = 0.0f; if (imageWidthHalved>self.view.frame.size.width/2.0f) { leftBorderLimit = self.view.frame.size.width - imageWidthHalved; rightBorderLimit = imageWidthHalved; } else { leftBorderLimit = imageWidthHalved ; rightBorderLimit = self.view.frame.size.width - imageWidthHalved; } float imageHeightHalved = KIMAGEHEIGHT * 0.5f; float topBorderLimit = 0.0f; float bottomBorderLimit = 0.0f; if (imageHeightHalved>self.view.frame.size.height/2.0f) { topBorderLimit = self.view.frame.size.height - imageHeightHalved; bottomBorderLimit = imageHeightHalved ; } else { topBorderLimit = imageHeightHalved ; bottomBorderLimit = self.view.frame.size.height - imageHeightHalved ; } if(pos.x < leftBorderLimit){ pos.x = leftBorderLimit; velocity = CGPointZero; }else if(pos.x > rightBorderLimit){ pos.x = rightBorderLimit; velocity = CGPointZero; } if(pos.y < topBorderLimit){ pos.y = topBorderLimit; velocity = CGPointZero; }else if(pos.y > bottomBorderLimit){ pos.y = bottomBorderLimit; velocity = CGPointZero; } _imageView.center = pos; }