关闭

iOS 仿百度外卖-首页重力感应

标签: iOS重力感应CoreMotionUIAccelerometer
543人阅读 评论(0) 收藏 举报
分类:

今天带来的是仿百度外卖首页的重力感应..(由于只能真机测试,手里测试机只有5s,所以有些地方并没有适配其他机型,需要的还需要根据真机自行适配)



来简单说下实现吧,之前重力感应都是用UIAccelerometer实现的,但是,好像是从iOS 4 以后,这个方法就废弃了,它被直接封装到了CoreMotion框架中,所以现在有关重力感应,加速计什么的都需要通过CoreMotion框架实现,这也算是苹果对于重力感应的整合吧.本文对CoreMotion框架只是进行了简单的使用,想要更深的使用,还是请自行 google(百度上的文档非常少).

好了.下面就是实现代码

(注意这里需要导入系统框架CoreMotion.framework)

//
//  ViewController.m
//  仿百度外卖首页-重力感应
//
//  Created by Amydom on 16/12/5.
//  Copyright © 2016年 Amydom. All rights reserved.
//

#import "ViewController.h"
#import <CoreMotion/CoreMotion.h>

@interface ViewController ()<UIScrollViewDelegate>{
    
    NSTimeInterval updateInterval;
    CGFloat  setx;//scroll的动态偏移量
    
}
@property (nonatomic,strong) CMMotionManager *mManager;

@property (nonatomic , strong)UIScrollView *myScrollView;

@property (nonatomic , assign)CGFloat offsetX;//初始偏移量

@property (nonatomic , assign)NSInteger offset;


@end

@implementation ViewController

- (void)viewDidAppear:(BOOL)animated_{
    
    [super viewDidAppear:animated_];
    //在界面已经显示后在调用方法(优化)
    [self startUpdateAccelerometerResult:0];
    
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    [self createView];
    
}

- (void)createView{
    
    //collectionView
    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init];
    UICollectionView *myCollection = [[UICollectionView alloc]initWithFrame:[UIScreen mainScreen].bounds collectionViewLayout:flowLayout];
    myCollection.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:myCollection];
    
    
    
    _myScrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 22, self.view.frame.size.width, 100)];
    _myScrollView.backgroundColor = [UIColor lightGrayColor];
    _myScrollView.delegate = self;
    [self.view addSubview:_myScrollView];
    
    
    for (int i = 0; i < 8; i ++) {
        
        NSString *name = [NSString stringWithFormat:@"%d.jpg",i + 1];
        UIImageView *image = [[UIImageView alloc]initWithFrame:CGRectMake(5 + 85 * i, 10, 80, 80)];
        image.image = [UIImage imageNamed:name];
        image.backgroundColor = [UIColor orangeColor];
        image.layer.masksToBounds = YES;
        image.layer.cornerRadius = 40;
        [_myScrollView addSubview:image];
        //偏移量为最后 image 的 frame + origin
        _myScrollView.contentSize = CGSizeMake (image.frame.size.width + image.frame.origin.x, 10);
        
        
    }
    
    

}

//手指触碰时
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    
     _offsetX = scrollView.contentOffset.x;
    [self stopUpdate];
    
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    
    //优化处理
    setx = scrollView.contentOffset.x;
    
    _offset = scrollView.contentOffset.x - _offsetX;
    
        if (_offset > 0) {
    
            //left
    
        }else{
    
            //right
            
        }
    
    
}
//手指离开时
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    
    [self startUpdateAccelerometerResult:0];
    
}

#pragma mark - 重力感应
- (CMMotionManager *)mManager
{
    if (!_mManager) {
        updateInterval = 1.0/15.0;
        _mManager = [[CMMotionManager alloc] init];
    }
    return _mManager;
}
//开始
- (void)startUpdateAccelerometerResult:(void (^)(NSInteger))result
{

    if ([self.mManager isAccelerometerAvailable] == YES) {
        //回调会一直调用,建议获取到就调用下面的停止方法,需要再重新开始,当然如果需求是实时不间断的话可以等离开页面之后再stop
        [self.mManager setAccelerometerUpdateInterval:updateInterval];
        [self.mManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error)
         {
             double x = accelerometerData.acceleration.x;
             double y = accelerometerData.acceleration.y;
             if (fabs(y) >= fabs(x))
             {//前后
                 if (y >= 0){
                     //Down
                 }
                 else{
                     //Portrait
                 }
                 
             } else { //左右
                
                 if (x >= 0){
                     
                     setx += 10;
                     
                     if (setx <= 360) {
                         //由于以10为单位改变 contentOffset, 会出现顿的现象,加上动画就可解决这个问题
                         [UIView animateWithDuration:0.1 animations:^{
                             
                             _myScrollView.contentOffset = CGPointMake(setx, 0);
                         }];
                         //模仿 scroll 的回弹效果
                         if (setx == 360) {
                             
                             [UIView animateWithDuration:0.5 animations:^{
                                 
                                 _myScrollView.contentOffset = CGPointMake(setx + 50, 0);
                                 
                             } completion:^(BOOL finished) {
                                 
                                 [UIView animateWithDuration:0.5 animations:^{
                                     
                                     _myScrollView.contentOffset = CGPointMake(setx , 0);

                                 }];
                                 
                             }];
                             
                         }
                         
                     }else{
                         
                         setx = 360;
                     }
                     
        
                 }else{
                     
                     setx -= 10;
                     
                     if (setx >= 0) {
                         
                         [UIView animateWithDuration:0.1 animations:^{
                             
                             _myScrollView.contentOffset = CGPointMake(setx, 0);

                         }];
                         
                         //模仿 scroll 的回弹效果
                         if (setx == 0) {
                             
                             [UIView animateWithDuration:0.5 animations:^{
                                 
                                 _myScrollView.contentOffset = CGPointMake(setx - 50, 0);
                                 
                             } completion:^(BOOL finished) {
                                 
                                 [UIView animateWithDuration:0.5 animations:^{
                                     
                                     _myScrollView.contentOffset = CGPointMake(setx, 0);
                                     
                                 }];
                                 
                             }];

                         }
                         
                     }else{
                         
                         setx = 0;
                         
                     }
                 }
             }
         }];
    }
}

//停止感应方法
- (void)stopUpdate
{
    if ([self.mManager isAccelerometerActive] == YES)
    {
        [self.mManager stopAccelerometerUpdates];
    }
}
//离开页面后停止(移除 mManager)
- (void)dealloc
{
    //制空,防止野指针
    _mManager = nil;
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

到这里,就可以进行真机测试了..

因为只是想简单的实现重力感应,所以效果上还是会差不少,毕竟水平有限吗........

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:54762次
    • 积分:1174
    • 等级:
    • 排名:千里之外
    • 原创:63篇
    • 转载:5篇
    • 译文:0篇
    • 评论:9条
    最新评论