iOS传感器:实现一个随屏幕旋转的图片

转载 2018年01月05日 00:00:00

点击上方“iOS开发”,选择“置顶公众号”

关键时刻,第一时间送达!

640?wxfrom=5&wx_lazy=1

0.gif?wxfrom=5&wx_lazy=1

真的是发现坚持写作,其实也是逼迫自己坚持不断学习的过程。那么,来来来,星辰大海我们又开始启程了。这次这个系列呐,我管它叫《iOS传感器小兄弟们》。先暂时这么叫着,等想到什么好听的名字再改。


?wx_fmt=other&wxfrom=5&wx_lazy=1


咳咳,下面这个计划就真的只是计划,反正现在先这么计划着。实在不行就改需求,需求就是用来改的......-_-+++。所以,以下目录 随时修改 仅供参考


  • 第一篇:加速传感器

  • 第二篇:陀螺仪

  • 第三篇:磁力计

  • 第四篇:距离传感器

  • 第五篇:指纹识别传感器

  • 第六篇:蓝牙之MultipeerConnectivity

  • 第七篇:蓝牙之Core Bluetooth

  • 第八篇:想个好玩的例子,把前面的都综合一下。


这个系列的内容模拟器基本上都不支持,需要真机测试才可以。所以掏出手机,咱们一起来搞事情吧。为了能够录到手机效果,也是小费了一番周折。


咱们通过实现一个随屏幕旋转的图片来看看加速计怎么玩。下面是完成后的效果视频截图,GIF图片的压缩效果也是刚刚的。请无视我的小背心:


?wx_fmt=gif


有一些APP除了绚丽的界面之外,还会有一些特殊的功能。例如微信的摇一摇,各种健康软件的计步器,指南针等等。这些APP其实都用到了iOS当中一个核心运动框架,叫做CoreMotion。


CoreMotion可以从内置的传感器中获取数据,这些传感器包括陀螺仪、加速器和磁力计。更值得嘚瑟的是,苹果集成了很多算法,可以直接输出剥离重力加速因素的加速度信息。好流弊的样纸。


1. 加速计介绍


iPhone、iPad、iWatch都可以测量x,y,x三个轴上的加速力。加速力就是当物体在加速过程中作用在物体上的力。用一张图说明一下下:


?wx_fmt=other


2. 加速计的使用


既然说了加速计是通过CoreMotion这个框架来管理的,而且苹果继承了辣么多算法,所以CoreMotion一定还有一个Manager。官方是这么介绍CMMotionManager:


A CMMotionManager object is the gateway to the motion services provided by iOS. These services provide an app with accelerometer data, rotation-rate data, magnetometer data, and other device-motion data such as attitude. These types of data originate with a device’s accelerometers and (on some models) its magnetometer and gyroscope.


所以只要使用Motion的服务,咱们一定需要使用CMMotionManager。


使用步骤如下:


  1. 初始化CMMotionManager管理对象;

  2. 调用管理对象的对象方法获取数据;

  3. 处理数据;

  4. 当不需要使用的时候,停止获取数据。


//初始化全局管理对象

- (CMMotionManager *)manager{

    if (!_manager) {

        _manager = [[CMMotionManager alloc] init];

   }

    return _manager;

}


//停止获取加速计数据。在停止之前判断一下是否还处在活动

    if (self.manager.accelerometerActive) {

         [self.manager stopAccelerometerUpdates];

         NSLog(@"关闭啦");

    }


3. 获取加速计数据的两种方式


CoreMotion中有2种获取数据方式,一种叫做PUSH的方式,一种叫做PULL的方式。


顾名思义,PUSH就是被动的获取。设定完了之后,线程定时把获取到的数据推送回来。可想而知,对于资源的消耗是会稍微大一点的。


PULL,就是要去索取。拉一下才会获取到数据。不要不给。


3.1 PULL的方式


- (void)useAccelerometerPull{

    //判断加速度计可不可用

    if (self.manager.accelerometerAvailable){

        //设置加速计多久采样一次

        self.manager.accelerometerUpdateInterval = 0.1;

        //开始更新,后台线程开始运行。这是Pull方式。

         [self.manager startAccelerometerUpdates];

     }

    //获取并处理加速度计数据。这里我们就只是简单的做了打印。

    NSLog(@"X = %f,Y = %f,Z = %f",self.manager.accelerometerData.acceleration.x,self.manager.accelerometerData.acceleration.y,self.manager.accelerometerData.acceleration.z);

}


3.2 PUSH的方式


- (void)useAccelerometerPush{

    //判断加速度计可不可用,判断加速度计是否开启

    if (self.manager.accelerometerAvailable){

        //设置加速计多久采样一次

        self.manager.accelerometerUpdateInterval = 0.1;

        //Push方式获取和处理数据,这里我们一样只是做了简单的打印。把采样的工作放在了主线程中。

         [self.manager?startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue]

                                    withHandler:^(CMAccelerometerData *accelerometerData, NSError *error){

        NSLog(@"X = %f,Y = %f,Z = %f",self.manager.accelerometerData.acceleration.x,self.manager.accelerometerData.acceleration.y,self.manager.accelerometerData.acceleration.z);

        }];

     }else{

        NSLog(@"不可用");

     }

}


3.3 打印结果


我们可以愉快的看到XYZ轴的数值在疯狂地变化。这中间我的手机屏幕一直在晃动。


?wx_fmt=gif


4. 实现图片永远水平方向


4.1 思路


STEP1:为了能够让图片无论在设备如何倾斜的情况下都保持水平,肯定首先要获取到屏幕的旋转。


STEP2:用很高的频率获取到这个数值之后,来旋转图片。


STEP 3: 就结束了。神马?!!!!开玩笑啦。其实在这个过程中可以发现,图片在旋转的时候会有一些抖动。肿么办呢?我们可以考对一定时间内获取的数据取平均值来缓和。在使用了下次文章介绍的陀螺仪之后,抖动效果也会得到明显的改善。这一部分的代码部分宅胖儿就没有实现了,自己尝试一下?!啦啦啦啦啦。


4.2 实现


- (void)keepBalance{

        if (self.manager.accelerometerAvailable) {

            //设置加速计采样频率

            self.manager.accelerometerUpdateInterval = 0.01f;

            [self.manager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData * _Nullable accelerometerData, NSError * _Nullable error) {

//                计算图片的水平倾斜角度。这里没有实现Z轴的形变,所以咱们只能在XY轴上变换。有兴趣的童鞋自己实现Z轴好不好?

            double rotation = atan2(accelerometerData.acceleration.x, accelerometerData.acceleration.y) - M_PI;

            self.imageView.transform = CGAffineTransformMakeRotation(rotation);

             }];

          }

}

4.3 关于形变角度atan2的说明


//计算旋转角度

double rotation = atan2(accelerometerData.acceleration.x, accelerometerData.acceleration.y) -M_PI;


这个里面用到了一个C语言的函数。atan2返回的是原点至点(x,y)的方位角,即与 x 轴的夹角。


你可能从未用过atan2这个函数,它和atan类似,但atan返回值范围是(-PI/2,PI/2),atan2返回值范围是(-PI,PI),并且他有两个参数。


atan2这个函数我们其实可以在很多地方都看到,Android、JS、PHP等等都能遇见到。如果想进一步深入了解,可以移步百度百科,感觉讲的还算挺清楚的。


好啦~手工~~~下次咱们用陀螺仪做一个水平滚动的小球的游戏玩玩~


源代码下载地址:OC+Swift两版。https://gitee.com/atypical/sensor



640?

  • 作者:非典型技术宅

  • 链接:https://juejin.im/post/5a2b6630f265da43052e8beb

  • iOS开发整理发布,转载请联系作者授权

0.gif

0?【点击成为Android大神】

iOS传感器:实现一个随屏幕旋转的图片

作者 非典型技术宅 关注 2017.05.24 17:22* 字数 1568 阅读 351评论 7喜欢 14 在写上一个动画系列的时候学到了非常多的知识,也认识了很多人。例如受...
  • qq_34047841
  • qq_34047841
  • 2017年06月07日 09:58
  • 613

iOS 屏幕旋转,单个屏幕旋转的实现

闲来无事研究了一下屏幕旋转的问题 说到屏幕旋转问题不得先说一句,做项目尽量还是优先使用storyboard、IB因为有了autolayout的约束布局为基础再去做屏幕旋转需要的视图布局适配就相对来说简...
  • u012884714
  • u012884714
  • 2016年04月21日 18:04
  • 1607

iOS中关闭屏幕旋转功能时如何判断屏幕方向

首先讲强制横屏和竖屏,其实很少App需要强制转屏的,一般在视频播放,相机这类需要旋转屏幕 (1)这段代码是直接横屏 (interfaceOrientation 这个枚举有各种情况) // 视图...
  • u012121216
  • u012121216
  • 2015年11月10日 14:17
  • 1072

IOS屏幕旋转的检测 与 强行切换

[[UIDevice currentDevice]setValue:[NSNumber numberWithInteger:sender.selected?UIDeviceOrientationLan...
  • Goods_boy
  • Goods_boy
  • 2017年05月22日 22:41
  • 472

横屏下UIWindow添加多个view自动旋转的解决方案

1、不要直接在UIWindow里面直接使用UIView,而是加载根试图控制器(UIViewController)然后使用控制器改变UIView,这也是Apple官方推荐的方式...
  • leikezhu1981
  • leikezhu1981
  • 2014年07月23日 23:19
  • 5667

iOS之屏幕旋转调用的方法

屏幕旋转调用的方法
  • u011146511
  • u011146511
  • 2016年05月12日 01:19
  • 1875

iOS监听屏幕旋转的几种方法

通过控制器得到 //获取将要旋转的状态 -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrien...
  • xuanai_xue123
  • xuanai_xue123
  • 2016年09月22日 09:29
  • 4896

iOS 屏幕旋转问题总结

1、两个Orientation1.1设备的物理方向(UIDeviceOrientation) typedef NS_ENUM(NSInteger, UIDeviceOrientation) { ...
  • sinat_29301173
  • sinat_29301173
  • 2017年02月24日 12:16
  • 931

ios(ipad,iphone)屏幕旋转检测通用方法

在特别的场景下,需要针对屏幕旋转作特殊处理。在ios系统下实现相关的功能还是比较方便的。 我下面介绍两种方法: 1.注册UIApplicationDidChangeStatusBarOrienta...
  • openglnewbee
  • openglnewbee
  • 2014年10月23日 21:26
  • 17625

[iOS]监控屏幕旋转

[iOS]监控屏幕旋转 - (void)viewDidLoad { [super viewDidLoad]; //设备旋转通知 [[UIDevice current...
  • u012881779
  • u012881779
  • 2016年03月07日 17:43
  • 1416
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS传感器:实现一个随屏幕旋转的图片
举报原因:
原因补充:

(最多只允许输入30个字)