推送通知/传感器/UIDynamic

一.推送通知

1.推送通知简介
  • 什么是推送通知
  • 此处的推送通知与NSNotification没有任何关系
  • 可以理解为,向用户推送一条信息来通知用户某件事情
  • 作用:可以在APP退到后台或者关闭时,继续推送一条消息告诉用户某件事情
  • 推送通知的应用场景
  • 任务管理类APP,会在任务时间即将到达时,通知做该做的任务
  • 即时通讯类APP,即使退到后台,或者关闭APP,也可以收到信息通知告诉用户
  • 电商APP,推送消息通知用户最新打折商品等
  • 推送通知的分类
  • 本地推送通知
  • 本地通知,即使在没有网络的情况下,也可以推送通知消息
  • 应用场景:确定知道未来某个时间点应该提醒用户什么
  • 远程推送通知
  • 概念:与本地通知相对,必须在联网情况下才会向用户推送通知消息
  • 远程推送服务有成为APNs(Apple Push Notification Service)
  • 应用场景1:不确定未来某个时间点应该提醒用户什么,临时性的
  • 应用场景2:当APP彻底退出时,也想继续让用户获取一些最新消息
  • 使用原则
  • 谁能确定通知时间和内容,谁就可以发送
  • 开发人员在APP内部通过代码发送->本地通知
  • 服务器可以确定通知时间和内容->远程通知
  • 推送通知的展现样式
  • 在屏幕顶部显示一块横幅(显示具体内容)
  • 在屏幕中间弹出一个UIAlertView(显示具体内容)
  • 在锁屏界面显示一块横幅(锁屏状态下,显示具体内容)
  • 更新APP图标的数字(说明新内容的数量)
  • 播放音效(提醒作用)
  • 注意:以上样式只能是用户自己设置,开发者无法通过代码控制
2.本地推送通知
  • 本地通知的基本使用
  1. 创建UILocalNotification对象
  2. 设置一些必要的属性
  • 推送通知的触发时间(何时发出推送通知)
  • @property(nonatomic,copy) NSDate *fireDate;
  • 推送通知的具体内容
  • @property(nonatomic,copy) NSString *alertBody;
  1. 开始推送通知
  • 根据fireDate设定的时间进行推送
  • [[UIApplication sharedApplication] scheduleLocalNotification];
  • 立即推送
  • presentLocalNotificationNow:(UILocalNotification *)notification;
  1. 取消调度本地推送通知
  • (void)cancelLocalNotification:(UILocalNotification *)notification;
  • (void)cancelAllLocalNotification;
  1. 获得被调度(定制)的所有本地推送通知
  • @property(nonatomic,copy) NSArray *scheduledLocalNotifications;
  • 已经发出且过期的推送通知一旦调度结束,会自动从这个数组中移除
  1. 注意事项
  • 在iOS8.0以后,如果要使用本地通知,需要得到用户的许可
  • 在didFinishLaunchingWithOptions方法中添加如下代码:
  • 设置通知的提示方式(badge图标/sound声音/alert)
  • [application registerUserNotificationSettings:settings];
  • 额外设置
  • 每隔多久重复发一次推送通知
  • @property(nonatomic) NSCalendarUnit repeatInterval;
  • 点击推送通知打开app时显示的启动图片
  • @property(nonatomic,copy) NSString *alertLaunchImage;
  • 额外的附加信息
  • @property(nonatomic,copy) NSDictionary *userInfo;
  • 时区
  • @property(nonatomic,copy) NSTimeZone *timeZone;
  • 一般设置为[NSTimeZone defaultTimeZone],跟随手机的时区
  • 在锁屏时显示的动作标题(完整标题:"滑动来"+alertAction)
  • @property(nonatomic,copy) NSString *alertAction;
  • 音效文件名
  • @property(nonatomic,copy) NSString *soundName;
  • app图标数字
  • @property(nonatomic) NSInteger applicationIconBadgeNumber;
  • 监听用户点击通知
  • app处于前台
  • 此时不会弹框通知用户通知的到达,但是还是会调用对应的代理方法
  • app没有关闭,隐藏在后台
  • 此时用户点击通知信息后,会让app进入前台,并会调用AppDelegate的下面方法
  • application:didReceiveLocalNotification:
  • app已经关闭(进程已死)
  • 此时用户点击通知信息后,会启动app,启动完毕会调用AppDelegate的下面方法
  • application:didFinishLaunchingWithOptions:
  • launchOptions参数通过UIApplicationLaunchOptionsLocalNotificationKey取出本地推送通知对象
  • 额外补充:在iOS8之后,可以设置推送通知带操作行为
  • 在注册设置时,设置categories:参数UIMutableUserNotification
  • identifier:动作标识
  • title:动作标题
  • activationMode:是前台运行,还是后台运行此动作
  • destructive:是否是破坏性动作(只是通过颜色,标识按钮,给用户提示)
  • behavior:动作行为(iOS9提供一个文本行为)
  • 监听通知操作行为的点击
  • application:handleActionWithIdentifier:forLocalNotification:completionHandler:
  • application:handleActionWithIdentifier:forLocalNotification:withResponseInfo:completionHandler:
3.远程推送通知
  • 远程推送的原理
  • 所有苹果设备,在联网状态下,都会与苹果服务器建立一个长连接
  • 长连接:
  • 优势:服务器可以向客户端发送消息,保证数据的即时性
  • 劣势:占用客户端和服务器资源
  • 短连接:
  • 优势:节省资源,一个会话结束后,立即释放资源
  • 劣势:服务器无法主动向客户端发信息
  • 苹果设备长连接的作用:
  • 时间校准
  • 系统升级
  • 查找我的iPhone
  • 推送通知
  • 原理就是借助苹果设备与APNs服务器之间的长连接,借助APNs服务器将消息发送给客户端,与QQ/微信的消息发送机制类似.
  • 远程推送通知实现,客户端需要做的事
  • 需要真机调试证书,推送测试证书
  • 请求苹果获得deviceToken
  • 注意:只有真机可以调试推送证书,因为只有真机才具备UDID,才能够生成deviceToken
  • 在iOS8之前,请求远程推送通知
  • [[UIApplication sharedApplication] registerForRemoteNotificationTypes:nil];
  • 在iOS8之后,请求远程推送通知
  • UIUserNotificationSettings *notificationSet = [[UIUserNotificationSettings settingsForTypes:nil categories:nil]];
  • [[UIApplication sharedApplication] registerForRemoteNotifications];
  • 当远程通知注册后,APNs会通过调用这个方法,返回对应的deviceToken
  • application:didRegisterForRemoteNotificationWithDeviceToken:
  • 得到苹果返回的deviceToken,发送deviceToken给公司的服务器
  • 远程推送测试(使用PushMeBaby)
  • 编译会出现错误,直接把错误行注释即可
  • 需要天街对应的deviceToken
  • 需要把推送测试证书改名为aps.cer拖入项目中
  • 监听用户对通知的点击
  • application:didReceiveRemoteNotification
  • application:didReceiveRemoteNotification:fetchCompletionHandler:
  • 当前在前台时,或者app在后台/app被彻底退出状态下,点击通知打开app进入前台,都可以执行以下方法
  • 执行completionHandler作用
  • 系统会估量app消耗的电量,并根据传递的UIBackgroundFetchResult参数记录新数据是否可用
  • 调用完成的处理代码时,应用的界面缩略图会自动更新
  • 如果想要接收到通知后,不要用户点击通知,就执行以下代码,那么必须有三个要求
  • 必须勾选后台模式Remote Notification
  • 告诉系统是否有新的内容更新(执行完成代码块)
  • 设置发送通知的格式("content-available":"随便传")
  • 第三方推送
  • 极光推送简介
  • 优势
  • 减少开发及维护成本
  • 应用开发者不需要去开发维护自己的推送服务器与APNs对接
  • 集成了JPush iOS SDK后不必自己维护更新deviceToken
  • 通过JPush的Web Portal直接推送,也可以调用JPush的HTTP协议API来完成,开发工作量大大减少
  • 减少运营成本
  • 极光推送支持一次推送,同时向Android/iOS/WinPhone三个平台.支持统一的API与推送界面.
  • 极光推送提供标签/别名绑定机制,以及提供了非常细分的用户分群方式,运营起来非常简单,直观.
  • 提供应用内消息推送
  • 除了使得APNs推送更简单,也另外提供应用内消息推送,这在类似于聊天的场景里很有必要.
  • 发送通知流程
  • app同时和极光服务器/苹果APNs服务器保持长连接
  • 当服务器需要向用户推送消息时,通过极光云,将要推送的消息发送到APNs后,由苹果服务器下发该消息
  • 对于应用内消息推送,极光云服务器可以直接与app保持长连接,来及时获取服务器下发的消息
  • 集成指导文档
  • 具体集成步骤以及使用方法
  • 配置证书(开发环境/生产环境下的推送P12证书)
  • 创建应用,上传待集成,发布的应用所使用的AppID的APNs证书
  • 在"iOS开发证书"选项中,选择导出的APNs Development iOS证书的.p12文件
  • 开发证书密码,需要与到处p12证书时设置的一致
  • 在"iOS生产证书"选项中,选择到处的Apple Push Service证书的.p12文件
  • 获取AppKey,集成过程中需要把该值配置到项目中
  • Bundle ID为上传的证书的BundleID,请确定与Xcode项目中info.plist中的Bundle Identifier一致
  • 下载SDK并集成到项目中
  • 解压SDK包,将解压后的lib子文件夹添加到工程目录中
  • 根据文档,添加必要的框架
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
      self.window.backgroundColor = [UIColor whiteColor];
      [self.window makeKeyAndVisible];

      // Required
      if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
         //可以添加自定义categories
        [JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
                                                          UIUserNotificationTypeSound |
                                                          UIUserNotificationTypeAlert)
                                               categories:nil];
      } else {
        //categories 必须为nil
        [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                          UIRemoteNotificationTypeSound |
                                                          UIRemoteNotificationTypeAlert)
                                              categories:nil];
     }

     // Required
     //如需兼容旧版本的方式,请依旧使用[JPUSHService setupWithOption:launchOptions]方式初始化和同时使用pushConfig.plist文件声明appKey等配置内容。
     [JPUSHService setupWithOption:launchOptions appKey:appKey channel:channel apsForProduction:isProduction];     
        return YES;
  }

  - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

     // Required
     [JPUSHService registerDeviceToken:deviceToken];
  }

  - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

      // Required,For systems with less than or equal to iOS6
     [JPUSHService handleRemoteNotification:userInfo];
  }

  - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

     // IOS 7 Support Required
     [JPUSHService handleRemoteNotification:userInfo];
     completionHandler(UIBackgroundFetchResultNewData);
  }

  - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {

     //Optional
     NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error); 
  }

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
      self.window.backgroundColor = [UIColor whiteColor];
      [self.window makeKeyAndVisible];

      // Required
      if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
         //可以添加自定义categories
        [JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
                                                          UIUserNotificationTypeSound |
                                                          UIUserNotificationTypeAlert)
                                               categories:nil];
      } else {
        //categories 必须为nil
        [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                          UIRemoteNotificationTypeSound |
                                                          UIRemoteNotificationTypeAlert)
                                              categories:nil];
     }

     // Required
     //如需兼容旧版本的方式,请依旧使用[JPUSHService setupWithOption:launchOptions]方式初始化和同时使用pushConfig.plist文件声明appKey等配置内容。
     [JPUSHService setupWithOption:launchOptions appKey:appKey channel:channel apsForProduction:isProduction];     
        return YES;
  }

  - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

     // Required
     [JPUSHService registerDeviceToken:deviceToken];
  }

  - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

      // Required,For systems with less than or equal to iOS6
     [JPUSHService handleRemoteNotification:userInfo];
  }

  - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

     // IOS 7 Support Required
     [JPUSHService handleRemoteNotification:userInfo];
     completionHandler(UIBackgroundFetchResultNewData);
  }

  - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {

     //Optional
     NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error); 
  }

iOS10推送通知适配
  • iOS10推送新增了UserNotifications.framwork,使用起来其实很简单
  • iOS10之前,点击通知栏,执行的回调方法
  • application:didReceiveRemoteNotification:
  • application:didReceiveRemoteNotification:fetchCompletionHandler:
  • iOS10推送通知
  • 在前台的时候回调(userNotificationCenter:willPresentNotification:withCompletionHandler:)
  • 在后台进入的时候回调(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:)
  • 使用步骤:
  • 导入头文件UserNotification/UserNotification.h
  • 在application:didFinishLaunchingWithOptions:中判断系统版本号,并注册通知(iOS8之前/iOS8-iOS9/iOS10三中情况下,注册通知的方式不一样)
  • 在对应的回调方法中,获取通知数据
  • 对于本地通知没有变化,依然回调(application:didReceiveLocalNotification:)

二.传感器

1.传感器简介
  • 简介:传感器是一种感应/检测装置,目前已经广泛应用于智能手机上
  • 作用:用户感应/检测设备周边的信息,不同类型的传感器,检测的信息也不一样
  • 使用场景:
  • 地图app中,判断手机的朝向
  • 在光线较暗的条件下,自动降低屏幕亮度
  • 打电话时,人脸贴近iPhone屏幕时,屏幕会自动锁屏
  • iPhone内置的传感器
  • 运动传感器/加速度传感器/加速计(Motion/Accelerometer Sensor)
  • 最早出现在iOS设备上的传感器之一
  • 加速计用于检测设备在X/Y/Z轴上的加速度(哪个方向有力的作用)
  • 应用场景:加速度计可以用于检测设备的摇晃/摇一摇/计步器
  • 环境光传感器(Ambient Light Sensor)
  • 是iOS/Mac设备中最为古老的传感器成员
  • 它能够让用户在使用的时候,眼镜更为舒适
  • 距离传感器(Proximity Sensor)
  • 用于检测是否有其他物体靠近设备屏幕
  • 磁力计传感器(Magnetometer Sensor)
  • 感应地球磁场,获得方向信息,使位置服务数据更精确
  • 用于电子罗盘和导航应用
  • iPad的Smart Cover盒盖睡眠操作就是基于磁力计传感器
  • 内部温度传感器(Internal Temperature Sensor)
  • 从iPad一代开始,iOS设备就加入了内部温度传感器,用于检测内部组件温度,当温度超过系统设定的阈值时,就会警告用户.
  • 湿度传感器(Moisture Sensor)
  • 湿度传感器和其他微电子的传感器不同,是一个简单的物理传感器
  • 简单来说,湿度传感器就是一张遇水变红的试纸
  • Apple的维修人员就是通过检测试纸是否变红,来判断设备是否进水(设备进水不在保修范围之内)
  • 陀螺仪(Gyroscope)
  • 陀螺仪是随着iPhone4的上市首次出现在iOS设备上的传感器
  • 陀螺仪可以用于检测设备的握持方式
  • 陀螺仪的原理是检测设备在X/Y/Z轴上所旋转的角度
  • 应用场景:
  • 陀螺仪在赛车类游戏中有重大作用
  • 模拟汽车驾驶时方向盘螺旋的动作,使得这类游戏的操控体验更为真实
2.常用传感器的实现
  • 距离传感器
  • 作用:检测是否有物体靠近设备
  • 应用场景:微信中的语音消息,如果把设备靠近耳边会启动听筒播放,如果离开,会启动扩音器播放
  • 使用步骤
  • 开启距离感应功能
  • [UIdevice currentDevice].proximityMonitoringEnalbe = YES;
  • 监听距离感应的通知
  • 通知名称:UIDeviceProximityStateDidChangeNotification
  • 实现监听方法
  • 在监听方法中,需要判断是否开启了距离感应功能,再决定是否执行相应的代码
  • 加速度计(iOS4以前)
  • 原理:检测设备在X/Y/Z轴上的加速度(哪个方向有力的作用,哪个方向运动了)
  • 根据加速度数值,可以判断出各个方向上的作用力度
  • 在iOS4以前,使用UIAccelerometer,用法非常简单(到了iOS5就已经过期),swift无法使用
  • 获得单例对象
  • UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
  • 设置代理
  • accelerometer.delegate = self;
  • 设置采样间隔(1秒钟采样30次)
  • accelerometer.updateInterval = 1.0/30.0;
  • 实现代理方法
  • accelerometer:didAccelerate
  • 加速度计(iOS4之后)
  • 从iOS4开始使用CoreMotion.framework
  • 使用变化
  • 随着iPhone4的推出,加速度计全面升级,并引入了陀螺仪
  • 与Motion(运动)相关的编程成为重头戏
  • 苹果特地在iOS4中增加了专门处理Motion的框架-CoreMotion.framework
  • CoreMotion不仅能够提供实时的加速度值和旋转速度值,更重要的是,苹果在其中继承了很多重要的算法
  • CoreMotion获取数据的两种方式
  • push:实时采集所有数据(采集频率高)
  • 优点:从不缺失采样,适用于数据采集app
  • 缺点:Increased overhead/Often best to drop samples
  • pull:在有需要的时候,再主动去采集数据
  • 优点:更加高效/需要的代码更少,蛇用于大多数app和游戏类app
  • 缺点:由于是在需要的时候主动采集,可能需要添加额外的定时器
  • CoreMotion的使用步骤
  • push
  1. 创建运动管理者对象
  • CMMotionManager *mgr = [[CMMotionManager alloc] init];
  1. 判断加速度计是否可用(最好判断)
  • if(mgr.isAccelerometerAvailable)
  1. 设置采样间隔(1秒钟采样30次)
  • mgr.accelerometerUpdateInterval = 1.0/30.0
  1. 开始采样(采样到数据就会调用handler,handler会在queue中执行)
  • startAccelerometerUpdatesToQueue:withHandler:
  • pull
  1. 创建运动管理者对象
  • CMMotionManager *mgr = [[CMMotionManager alloc] init];
  1. 判断加速度计是否可用(最好判断)
  • if(mgr.isAccelerometerAvailable)
  1. 开始采用
  • startAccelerometerUpdates
  1. 在需要的时候采集加速度数据
  • CMAcceleration acc = mgr.accelerometerData.acceleration;
  • 摇一摇
  • 方法1:通过分析加速度数据来判断是否进行了摇一摇操作(复杂)
  • 方法2:iOS自带的Shake监控API(简单)
  • 实现3个摇一摇监听方法
  • 检测到摇动:motionBegan:withEvent:
  • 摇动取消(被中断):motionCancelled:withEvent:
  • 摇动结束:motionEnded:withEvent:
  • 计步器
  • 功能作用:判断走了多少步/判断爬了多少楼层
  • 实现步骤:
  • CMStepCounter(iOS8之前)
  • 判断计步器是否可用
  • [CMPedometer isStepCountingAvailable];
  • 创建计步器对象
  • CMPedometer *stepCounter = [[CMPedometer alloc] init];
  • 开始计步
  • [stepCounter startPedometerUpdatesFromDate:nil withHandler:nil];

三.UIDynamic

1.物理引擎UIDynamic简介
  • 什么是UIDynamic?
  • UIDynamic是从iOS7开始引入的一种新技术,隶属于UIKit框架
  • 可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象(重力/弹性碰撞等现象)
  • 物理引擎的价值
  • 广泛用于游戏开发,经典成功案例是"愤怒的小鸟"
  • 让开发人员可以在原理物理学公式的情况下,实现炫酷的物理方针效果
  • 提高了游戏开发效率,产生更多优秀好玩的物理仿真游戏
2.UIDynamic的使用步骤
  • 使用步骤
  • 创建一个物理仿真器(顺便设置仿真范围)
  • 创建相应的物理仿真行为(顺便添加物理仿真元素)
  • 将物理仿真行为添加到物理仿真器中,开始仿真
  • 三大概念
  • 物理仿真元素(Dynamic Item)
  • 谁要进行物理仿真
  • 注意:不是任何对象都能做物理仿真元素/不是任何对象都能进行物理仿真
  • 哪些对象才能做物理仿真元素
  • 任何遵守了UIDynamicItem协议的对象
  • UIView默认已经遵守了UIDynamicItem协议,因此任何UI控件都能做物理仿真
  • UICollectionViewLayoutAttributes类也默认遵守了UIDynamicItem协议
  • 物理仿真行为(Dynamic Behavior)
  • 执行怎样的物理仿真效果?怎样的动画效果?
  • UIDynamic提供了以下几种物理仿真行为
  • UIGravityBehavior:重力行为
  • UICollisionBehavior:碰撞行为
  • UISnapBehavior:捕捉行为
  • UIPushBehavior:推动行为
  • 物理仿真行为须知
  • 上述所有物理仿真行为都继承自UIDynamicBehavior
  • 所有的UIDynamicBehavior都可以独立进行
  • 组合使用多种行为时,可以实现一些比较复杂的效果
  • 物理仿真器(Dynamic Animator)
  • 让物理仿真元素执行具体的物理仿真行为
  • 物理仿真器须知
  • 他可以让物理仿真元素执行物理仿真行为
  • 它是UIDynamicAnimator类型的对象
  • UIDynamicAnimator的初始化
  • (instancetype)initWithReferenceView:(UIView *)view;
  • view参数:是一个参照视图,表示物理仿真的范围
  • UIDynamicAnimator的常见方法
  • 添加1个物理仿真行为(addBehavior:)
  • 移除1个物理仿真行为(removeBehavior:)
  • 移除之前添加过的所有物理仿真行为(removeAllBehavior)
  • UIDynamicAnimator的常见属性
  • 参照视图
  • @property(nonatomic,readonly) UIView *referenceView;
  • 添加到物理仿真器中的所有物理仿真行为
  • @property(nonatomic,readonly,copy) NSArray *behaviors;
  • 是否正在进行物理仿真
  • @property(nonatomic,readonly,getter=isRunning) BOOL running;
  • 代理对象(能监听物理仿真器的仿真过程,比如开始和结束)
  • @property (nonatomic,assign) id delegate;
3.常用行为演练
  • 使用技巧:根据仿真元素创建仿真行为,添加到仿真器即可执行该方法
  • 重力行为(UIGravityAnimator)
  • 简介:给定重力方向/加速度,让物体朝着重力方向掉落
  • 初始化:initWithItems:(参数中存放着物理仿真元素)
  • 常见方法:添加1个物理仿真元素(addItem)
  • 常见属性:
  • 添加到重力行为中的所有物理仿真元素:NSArray *items;
  • 重力方向(二维向量):CGVector gravityDirection;
  • 重力方向(是一个角度,以x轴正方向为0°,顺时针为正,逆时针为负):CGFloat angle;
  • 量级(用来控制加速度,1.0代表加速度是1000点/秒的平方):CGFloat magnitude;
  • 演练步骤:
  1. 创建物理仿真器
  • _animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
  1. 根据仿真元素创建重力仿真行为
  • UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[self.boxView]];
  1. 设置重力角度
  • gravityBehavior.angle = M_PI*0.5;
  1. 设置量级
  • gravityBehavior.magnitude = 1;
  1. 添加仿真行为到仿真器,开始仿真
  • [self.animator addBehavior:gravityBehavior];
  • 碰撞行为(UICollisionAnimator)
  • 简介:可以让物体之间实现碰撞效果,可以通过添加便捷(boundary),让物理碰撞局限在某个空间中
  • 边界相关的方法
  • addBoundaryWithIdentifier:forPath:
  • addBoundaryWithIdentifier:fromPoint:toPoint:
  • boundaryWithIdentifier:
  • removeBoundaryWithIdentifier:
  • NSArray *boundaryIdentifiers;
  • removeAllBoundaries;
  • 常见用法
  • 是否以参照视图的bounds为边界
  • BOOL translatesReferenceBoundsIntoBoundary;
  • 设置参照视图的bounds为边界,并设置内边框
  • setTranslatesReferenceBoundsIntoBoundaryWithInsets:
  • 碰撞模式(分为3中,元素碰撞/边界碰撞/全体碰撞)
  • UICollisionBehaviorMode collisionMode;
  • 只碰撞物体,不碰撞边界(UICollisionBehaviorModeItems=1<<0)
  • 只碰撞边界,不碰撞物体(UICollisionBehaviorModeBoundaries=1<<1)
  • 边界和物体都碰撞(UICollisionBehaviorModeEverything=NSUIntegerMax)
  • 演练步骤
  1. 创建物理仿真器
  2. 根据仿真元素创建碰撞仿真行为
  3. 设置是否以参照视图的bounds为边界
  4. 设置碰撞模式
  5. 添加仿真行为到仿真器,开始仿真
  • 捕捉行为(UISnapAnimator)
  • 简介:可以让物体迅速冲到某个位置(捕捉位置),捕捉到位置之后会带有一定的震动
  • 初始化:initWithItem:snapToPoint:
  • 常见属性:CGFloat damping;(用于减幅/减震,取值范围0.0~1.0,值越大,震动幅度越小)
  • 使用注意:如果要进行连续的捕捉行为,需要先把前面的捕捉行为熊物理仿真器中移除
  • 演练步骤
  1. 创建物理仿真器
  2. 注意:如果想多次执行捕捉行为,需要在捕捉之前移除前面添加的捕捉行为
  3. 创建捕捉行为
  4. 设置振幅
  5. 添加仿真行为到仿真器,开始仿真
  • 推动行为(UIPushAnimator)
  • 简介:可以向某个方向,推动某个物体
  • 初始化:initWithItems:mode:
  • UIPushBehaviorMode
  • UIPushBehaviorModeContinuous:持续,一直推
  • UIPushBehaviorModeInstantaneous:不持续,推一下就放开
  • 常见属性:CGVector pushDirection;(推送方向,是一个向量,其坐标系与屏幕坐标系一致)
  • 演练步骤:
  1. 创建物理仿真器
  2. 根据仿真元素创建推动仿真行为
  3. 设置推动方向
  4. 添加仿真行为到仿真器,开始仿真