iOS印象笔记交互动画 OC完善版本

前人种树

一直想知道 iOS 端的印象笔记(当然是老版本了,最新的印象笔记已经放弃了这个坑人的动画)是如何实现的,在网上搜到了这篇印象笔记交互效果(swift),UI 和效果做得都非常好。于是乎怎么也得学习学习吧,用 OC copy 一份吧。于是乎开始了踩坑之路。

首先,allsome(swift 印象笔记作者)这个 Demo,实现思路是首页使用 UICollectionView 实现,滑动时候实时改变 cell 的 frame 实现类似弹簧的效果。但是, 其实这个 Demo有很多的 bug 没有处理,但是仍然是一个很好的思路,要不是这个 Demo,估计自己怎么也写不出这个动画。

然后,这个 Demo 的 bug 其实并不是那么容易处理的,我特意抓取了印象笔记 7.18 版本的旧包,发现印象笔记原版也存在这个 bug,说不定这就是他们改版的原因呢,哈哈。

下面具体看下这个 bug,

iOS印象笔记交互动画 OC完善版本_第1张图片
bug.gif

造成这个 bug 的主要原因还是用了手势,在自定义专场中使用了转场手势,根据手势偏移比例可以控制转场的进度。

熟悉转场动画的人应该知道,手势驱动有一个 bug:假如你设定,拖拽比例超过0.5,才决定完成动画,否则取消动画。那么当你拖拽比例是0.3的时候,那转场动画就进行0.3的比例,这个时候松手,转场动画会重新回到0,但是屏幕会闪一下。也就是转场从0.3直接回到了0,没有任何过渡,所以视觉上会闪一下。

等等,这个 bug 并不是每个转场动画都会有的,要看你怎么转了,这句话怎么讲?我在学习转场动画的时候看了喵神的博客里iOS7中的 VC 切换,里面的 demo 并不会因为拖拽比例不足返回时发生卡顿,效果如下

iOS印象笔记交互动画 OC完善版本_第2张图片
无宽高改变.gif

因为这个 Demo,在 dismiss 控制器的时候只是简单的让控制器 y 的值从上往下偏移了一个屏幕的距离,没有任何宽度和高度的改变,不会触发这个 bug。我把这个 Demo 简单的改了一下,dismiss 的时候会同时改变控制器的宽和高,然后这个恶心的 bug 就会出现了


iOS印象笔记交互动画 OC完善版本_第3张图片
宽高改变.gif
后人完善

我在wazrx的这篇文章中找到了解决方案,那就是在手势拖拽比例达不到我们指定的比例时,开启一个CADisplayLink定时器不断更新转场的进度,比较好的解决了动画生硬这个问题。

解决这个主要的 bug 之后,自己再把一些细枝末节完善了一下,就写成了现在这个 印象笔记 OC

iOS印象笔记交互动画 OC完善版本_第4张图片
oc.gif
总结

简单说一下完成印象笔记的这个Demo需要哪些知识点吧, 其实就两个:

  1. 弹簧效果(严格说这个 demo 实现的并不是弹框效果,没有使用到UIDynamic的性质)
  2. 自定义转场

在写这个 Demo 之前特意看了喵神的弹簧效果笔记。但是看到 swift 版本的 Demo 的时候发现原作者并没有使用这个效果,而是在 collectionView 滑动的时候动态计算了每个 cell 的 frame,改变了每个 cell 的 y 值,从而实现了这个效果,不得不说非常棒!因为如果使用了 UIDynamic 实现弹簧效果,在点击 cell 进入转场动画的时候会非常混乱。所以原作者这个方法简单,实用!

转场动画具体介绍网上实在太多了,可以自行百度,google。主要思想其实是: 以前怎么 modal 一个控制器是系统自己决定的,怎么 dismiss 也是系统决定的。 iOS7之后,Apple 提供了一套 API 给我们,我们可以自己决定如何 dismiss,如何 modal。

在allsome的 swift 版本的 demo 中,所有转场代理都在一个文件里,我为了让结构更加清晰,把转场代理全部分开,一共三个文件。

  1. 告诉我你想如何 present 一个控制器。
  2. 告诉我你想如何 dissmiss 掉一个控制器。
  3. 告诉我你手势驱动比例和dismiss 控制器的关系。
iOS印象笔记交互动画 OC完善版本_第5张图片
Snip20170510_1.png
最后的一点讨论

这个 Demo 中,点击 collectionView 的 cell,present出 MYNoteVC。
然后在使用手势 dismiss 的时候,只要手势开始 MYNoteVC 的 view 就被我们隐藏了,动画效果全部在 collectionView 上完成,所以手势没有完成的时候开启定时器,我们其实是对collectionView 做动画,正因为这个特性,才能使用定时器这个技巧解决动画生硬的问题。 如果我们直接对 MYNoteVC 做动画的话,定时器这个技巧也不能很好的完成这个动画,但是为什么wazrx的这篇文章的 Demo 里都没有任何不妥呢,原因有两个

  • wazrx 的这个 Demo 里 A -> B,B在dismiss 的时候实际上是对 B 的 view 的截图进行动画,并不是真正的 B 的 View。那印象笔记的 Demo 为什么不能对截图做动画呢? 因为还要实时改变控制器 title 和返回图标的 frame 和 alpha。

  • 印象笔记的 Demo 里 A -> B, B在dismiss的时候是先隐藏 B,实际对 A 进行动画。因为 A 和 B 长得一样,所以并看不出来。如果 B在 dismiss 的时候就真的对 B 进行动画,那么手势取消的时候还是会有bug。

本文 Demo
allsome的印象笔记 Swift
wazrx转场取消时开启定时器文章

好像也没什么可说的,只有动手写了,才更明白。

你可能感兴趣的:(iOS印象笔记交互动画 OC完善版本)