在手游中用到传感器的不少,平时你也可能会用到iOS 加速器,这时就会用到传感器,经过一个demol简单的讲一下iOS传感器app
建立一个UI View,经过代理方法时刻来更新加速度,时刻更新坐标ide
#import <UIKit/UIKit.h>动画
#import <CoreMotion/CoreMotion.h>atom
/* 协议给delegation使用,可以告诉label,如今x和y方向上实时更新的加速度 */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
#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