iOS 传感器

在手游中用到传感器的不少,平时你也可能会用到iOS 加速器,这时就会用到传感器,经过一个demol简单的讲一下iOS传感器app


建立一个UI View,经过代理方法时刻来更新加速度,时刻更新坐标ide

#import <UIKit/UIKit.h>动画

#import <CoreMotion/CoreMotion.h>atom

/* 协议给delegation使用,可以告诉label,如今xy方向上实时更新的加速度 */spa

@protocol GravityBallViewDelegate3d

- (void)updateLabelWithX:(double)accelerometerX Y:(double)accelerometerY;代理

// 代理方法code

@endorm



@interface GravityBallView : UIView ci

@property (nonatomic, strong) CMMotionManager *mManager;

// 代理人

@property (nonatomic, weak) id<GravityBallViewDelegate> delegate;


- (void)startUpdateAccelerometer;

- (void)stopUpdate;

@end





#import "GravityBallView.h"


@interface GravityBallView()

@property (readwrite) float velocity;

@end


// 坐标的变化过程

@implementation GravityBallView

@synthesize velocity;

@synthesize mManager = _mManager;

@synthesize delegate;


/* designate initializer */

- (id)initWithFrame:(CGRect)frame

{


    self = [super initWithFrame:frame];

    if (self) {

        _mManager = [[CMMotionManager alloc] init];

        /* 小球运动的速度(加速度的倍数),越大球运动越快,感受上越灵敏 */

        self.velocity = 200;

    }

    return self;

}

/* lazy init */

- (CMMotionManager *)mManager

{

    if (!_mManager) {

        _mManager = [[CMMotionManager alloc] init];

    }

    return _mManager;

}


- (void)startUpdateAccelerometer

{

    /* 设置采样的频率,单位是秒 */

    NSTimeInterval updateInterval = 0.07;

    

    CGSize size = [self superview].frame.size;

__block CGRect f = [self frame];

    

    //block中,只能使用weakSelf

    GravityBallView * __weak weakSelf = self;

    

    /* 判断是否加速度传感器可用,若是可用则继续 */

    if ([self.mManager isAccelerometerAvailable] == YES) {

        /* 给采样频率赋值,单位是秒 */

        [self.mManager setAccelerometerUpdateInterval:updateInterval];


        /* 加速度传感器开始采样,每次采样结果在block中处理 */

        [self.mManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error)

        {

            f.origin.x += (accelerometerData.acceleration.x * weakSelf.velocity) * 1;

            f.origin.y += (accelerometerData.acceleration.y * weakSelf.velocity) * -1;


            if(f.origin.x < 0)

                f.origin.x = 0;

            if(f.origin.y < 0)

                f.origin.y = 0;

            

            if(f.origin.x > (size.width - f.size.width))

                f.origin.x = (size.width - f.size.width);

            if(f.origin.y > (size.height - f.size.height))

                f.origin.y = (size.height - f.size.height);

            

            /* 运动动画 */

            [UIView beginAnimations:nil context:nil];

            [UIView setAnimationDuration:0.1];

            [weakSelf setFrame:f];

            [UIView commitAnimations];

            

            [weakSelf.delegate updateLabelWithX:accelerometerData.acceleration.x Y:accelerometerData.acceleration.y];

        }];

    }


}

/*

// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect

{

    // Drawing code

}

*/


/* 中止传感器,当不是用的时候要及时停掉 */

- (void)stopUpdate

{

    if ([self.mManager isAccelerometerActive] == YES)

    {

        [self.mManager stopAccelerometerUpdates];

    }


}



@end



//  ViewController.h

#import <UIKit/UIKit.h>

#import "GravityBallView.h"



@interface ViewController : UIViewController <GravityBallViewDelegate>

@property (nonatomic, strong) GravityBallView *gravityBallView;

@property (nonatomic, strong) UIImageView *imageView;

@end


// 

#import "ViewController.h"


@interface ViewController ()

@property (nonatomic, strong) UIButton *button;

@property (nonatomic, strong) UIView *bounderView;

@property (nonatomic, strong) UILabel *label;

@end


@implementation ViewController

@synthesize gravityBallView = _gravityBallView;

@synthesize imageView = _imageView;

@synthesize button = _button;

@synthesize bounderView = _bounderView;

@synthesize label = _label;

- (void)viewDidLoad

{

    [super viewDidLoad];

    _bounderView = [[UIView alloc] init];

    [_bounderView setFrame:CGRectMake(5, 5, 320 - 10, 400 - 10)];//是否是self自带的这个view是不能改大小的?原来的写法是直接self.view setFrame无论用。

    [_bounderView setBackgroundColor:[UIColor colorWithRed:0.2 green:0.8 blue:0.2 alpha:0.7]];

    [self.view addSubview:_bounderView];

    

    CGRect gravityBallViewFrame = CGRectMake(0, 0, 40, 40);

    _gravityBallView = [[GravityBallView alloc] initWithFrame:gravityBallViewFrame];

    [_bounderView addSubview:_gravityBallView];

    _gravityBallView.delegate = self;

    

    _imageView = [[UIImageView alloc] initWithFrame:gravityBallViewFrame];

    _imageView.image = [UIImage imageNamed:@"billiard.png"];

    [_gravityBallView addSubview:_imageView];

    

    [_gravityBallView startUpdateAccelerometer];

    

    _label = [[UILabel alloc] initWithFrame:CGRectMake(10, 400, 200, 50)];

    _label.backgroundColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.8 alpha:0.6];

    [self.view addSubview:_label];

    

    

    _button = [[UIButton alloc] initWithFrame:CGRectMake(220, 405, 90, 40)];

    _button.backgroundColor = [UIColor colorWithRed:0.8 green:0.2 blue:0.2 alpha:0.6];

    [_button setTitle:@"stop" forState:UIControlStateNormal];

    [_button addTarget:self action:@selector(onButtonClicked:) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:_button];


}

- (void)onButtonClicked:(UIButton*)button{

    if ([_gravityBallView.mManager isAccelerometerActive] == YES)

    {

        [_gravityBallView stopUpdate];

        [_button setTitle:@"start" forState:UIControlStateNormal];

    } else if(([_gravityBallView.mManager isAccelerometerActive] != YES) &&

              ([_gravityBallView.mManager isAccelerometerAvailable] == YES))

    {

        [_gravityBallView startUpdateAccelerometer];

        [_button setTitle:@"stop" forState:UIControlStateNormal];

    }

    else

    {

        NSLog(@"what's happenning?\n");

    }


}

- (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


- (void)viewWillDisappear:(BOOL)animated

{

    [_gravityBallView stopUpdate];

}


#pragma GravityBallViewDelegate

- (void)updateLabelWithX:(double)accelerometerX Y:(double)accelerometerY

{

    self.label.text = [NSString stringWithFormat:@"X:%f-Y:%f", accelerometerX, accelerometerY];

}

@end