iOS-重力感应
iOS-重力感应
麦兜卖鱼丸 发表于1年前
iOS-重力感应
  • 发表于 1年前
  • 阅读 8
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

摘要: 重力感应,实现摇一摇的功能,也可以模拟像游戏中通过重力操作物体的方向的功能。

前言

对于应用的交互,重力感应的加速器和陀螺仪可以开创一些比较新颖的交互方式,比如使用加速器实现摇一摇功能,使用陀螺仪实现图片跟随设备旋转或者是敲击反应(实现pop back效果)等等;

 

(一)利用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,达到不移动的效果。此方法参考至这篇文章

 

总结

以上只是实现了摇一摇的功能,一个简单的效果,其他的更好更复杂功能,大家可以去实践,通过cmmotionmanager获取得到数据,然后通过数据的计算,实现你想要的效果。

共有 人打赏支持
粉丝 13
博文 56
码字总数 69333
×
麦兜卖鱼丸
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: