适配iOS11:监控UICollisionBehavior结束

前言

上周在外出差一周,没有时间更新文章。而在9/20,iOS11正式发布。于是,需要对现有App进行兼容性测试了。当然,有条件的,应该在beta时就做好兼容性的准备。

问题

一启动App就发现问题了:在iOS11上打开后,一直在启动动画界面(非launch screen,是自定义的VC);而iOS11之前的系统都能正常工作。经检查,在启动界面,app等待两件事:

  1. 等待动画结束
  2. 等待后台连接完成

因为之前后台建立连接会不稳定,这一次先从2着手。但是没想到,排查后没有发现异常。不得已,再检查事件1,终于确认问题所在。

解决

动画是使用 UIDynamicAnimator 实现,具体就是一个view从屏幕中间出现后,自由落体,碰撞到屏幕底部反弹几下后,停在屏幕底部。原实现如下:

UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
self.dynamicAnimator = animator;
//自由落体
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.label]];
[self.dynamicAnimator addBehavior:gravity];
//碰撞
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.label]];
collisionBehavior.collisionMode = UICollisionBehaviorModeEverything;
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
collisionBehavior.collisionDelegate = self;
[self.dynamicAnimator addBehavior:collisionBehavior];

在iOS11之前, UICollisionBehaviorDelegate 在碰撞的时候会响应。查看 UICollisionBehavior 相关文档,没有发现在iOS11上有更新,那么势必要修改动画的实现了。考虑到现有实现,是通过设置 translatesReferenceBoundsIntoBoundary 属性,猜想显式地添加view的boundary:

 UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.view.frame];
[collisionBehavior addBoundaryWithIdentifier:@"Test" forPath:path];

运行后,发现 UICollisionBehaviorDelegate 的方法响应了!

Marketing icon

另外重要的一点:使用Xcode9提交的App,必须包含 1024x1024 的 marketing icon,切记切记!
接下来的时间,需要好好适配 iPhone X~

NSPhotoLibraryAddUsageDescription

iOS11引入的和Privacy有关的属性:当需要把图片存储到 Photos 时,必须在plist文件中声明。