[置顶] IOS的重力感应

     昨天写了重力感应的例子,我觉得这个例子比较有用处,我分享出来:

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

CMMotionManager 将是我们使用的Object,可以用来监测重力!

同时,咱们不能在需要监测重力感应的地方直接使用这个类,这样耦合比较严重,也不利于重用。所以抽离出来,在代码中您可以看到,我将定义一个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];
    
}

_imageView 是一个UIImageView的成员,其宽高是一个分别是我定义的宏。

注意,我在头文件添加了重力感应的代理,此时这行

[[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;
}

上面是对于边界的处理等等操作,都很简单,不一一介绍了。


你可能感兴趣的:(ios,object,iPhone,Class,float,interface)