iOS-重力感應

前言函數

對於應用的交互,重力感應的加速器和陀螺儀能夠開創一些比較新穎的交互方式,好比使用加速器實現搖一搖功能,使用陀螺儀實現圖片跟隨設備旋轉或者是敲擊反應(實現pop back效果)等等;atom

 

(一)利用cmmotionmanager獲取設備的及速度實現搖一搖的功能,再配合上本身設計的業務邏輯,就能夠現實市面上不少應用的搖一搖功能了。設計

#import "MotionViewController.h"
#import <CoreMotion/CoreMotion.h>
#import "FloatTextField.h"

static const double accelerationThreshold = 2.0f;

@interface MotionViewController ()

@property CMMotionManager *motionManager;
@property NSOperationQueue *operationQueue;

@property (nonatomic, strong) UIImageView *image;

@end

@implementation MotionViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    _operationQueue = [[NSOperationQueue alloc] init];
    
    _motionManager = [CMMotionManager new];
    _motionManager.accelerometerUpdateInterval = 1.0f / 60;
    
    
    _image = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    _image.center = self.view.center;
    _image.backgroundColor = [UIColor blueColor];
    
    
    [self.view addSubview:_image];
    
    FloatTextField *textfield = [[FloatTextField alloc] initWithFrame:CGRectMake(0, 100, 200, 40)];
    textfield.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:textfield];
}

- (void)viewDidAppear:(BOOL)animated {
    
    [super viewDidAppear:animated];
    [self startAccelermeter];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification:) name:UIApplicationDidEnterBackgroundNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification:) name:UIApplicationWillEnterForegroundNotification object:nil];
}


- (void)receiveNotification:(NSNotification *)notification {
    
    if ([notification.name isEqualToString:UIApplicationDidEnterBackgroundNotification]) {
        
        [_motionManager stopAccelerometerUpdates];
    } else {
        
        [self startAccelermeter];
    }
}


- (void)startAccelermeter {
    
    [_motionManager startAccelerometerUpdatesToQueue:_operationQueue withHandler:^(CMAccelerometerData * _Nullable accelerometerData, NSError * _Nullable error) {
        
        [self outputaccelerometerData:accelerometerData.acceleration];
    }];
}

- (void)outputaccelerometerData:(CMAcceleration)acceleration {
    
    double accelermeter = sqrt(pow(acceleration.x, 2) + pow(acceleration.y, 2) + pow(acceleration.z, 2));
    if (accelermeter > accelerationThreshold) {
        
        [_motionManager stopAccelerometerUpdates];
        [_operationQueue cancelAllOperations];
        
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            
            [self turnRight];
        }];
    }
}


-(void)setAnchorPoint:(CGPoint)anchorPoint forView:(UIView *)view
{
    CGPoint newPoint = CGPointMake(view.bounds.size.width * anchorPoint.x,
                                   view.bounds.size.height * anchorPoint.y);
    CGPoint oldPoint = CGPointMake(view.bounds.size.width * view.layer.anchorPoint.x,
                                   view.bounds.size.height * view.layer.anchorPoint.y);
    
    newPoint = CGPointApplyAffineTransform(newPoint, view.transform);
    oldPoint = CGPointApplyAffineTransform(oldPoint, view.transform);
    
    CGPoint position = view.layer.position;
    
    position.x -= oldPoint.x;
    position.x += newPoint.x;
    
    position.y -= oldPoint.y;
    position.y += newPoint.y;
    
    view.layer.position = position;
    view.layer.anchorPoint = anchorPoint;
}


- (void)turnRight {
    
    CABasicAnimation *rotate = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    rotate.fromValue = [NSNumber numberWithFloat:0];
    rotate.toValue = [NSNumber numberWithFloat:M_PI / 3.0];
    rotate.duration = 0.18;
    rotate.repeatCount = 2;
    rotate.autoreverses = YES;
    
    [CATransaction begin];
    [self setAnchorPoint:CGPointMake(-0.2, 0.9) forView:_image];
    [CATransaction setCompletionBlock:^{
        
        [self getData];
    }];
    
    [_image.layer addAnimation:rotate forKey:nil];
    
    [CATransaction commit];
}


- (void)getData {
    
    [self startAccelermeter];
}
@end

解釋一下-(void)setAnchorPoint:(CGPoint)anchorPoint forView:(UIView *)view函數,此函數是經過設置的anchorPoint,計算出對應的position,達到不移動的效果。此方法參考至這篇文章code

 

總結orm

以上只是實現了搖一搖的功能,一個簡單的效果,其餘的更好更復雜功能,你們能夠去實踐,經過cmmotionmanager獲取獲得數據,而後經過數據的計算,實現你想要的效果。server

相關文章
相關標籤/搜索