昨天寫了重力感應的例子,我覺得這個例子比較有用處,我分享出來:
1 )顯然ios4 之後可以使用coreMotion的framework 為了向下兼容加上UIAccelerator,
[html]
#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
CMMotionManager 將是我們使用的Object,可以用來監測重力!
同時,咱們不能在需要監測重力感應的地方直接使用這個類,這樣耦合比較嚴重,也不利於重用。所以抽離出來,在代碼中您可以看到,我將定義一個signleton,同時將重力變化的事件回調給其代理。
2.接著往下是定義其函數,這個很簡單,直接貼代碼。
[html]
#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 為例介紹如何使用重力感應
[html]
- (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];
}
_imageView 是一個UIImageView的成員,其寬高是一個分別是我定義的宏。
注意,我在頭文件添加了重力感應的代理,此時這行
[[IFAccelerometer shareAccelerometer]addOberser:self];
表明我在這個viewController中使用這個重力感應的數據。
好,現在是完成回調的時候了,繼續貼代碼
[html]
- (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;
}
上面是對於邊界的處理等等操作,都很簡單,不一一介紹了。