-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path倚天屠龙记.txt
executable file
·1 lines (1 loc) · 5.33 KB
/
倚天屠龙记.txt
1
UIScrollView可以说是UIKit中最重要的类之一了,包括UITableView和UICollectionView等重要的数据容器类都是UIScrollView的子类。在历年的WWDC上,UIScrollView和相关的API都有专门的主题进行介绍,也可以看出这个类的使用和变化之快。今年也不例外,因为iOS7完全重新定义了UI,这使得UIScrollView里原来不太会使用的一些用法和实现的效果在新的系统中得到了很好的表现。另外,由于引入了UIKit Dynamics,我们还可以结合ScrollView做出一些以前不太可能或者需要花费很大力气来实现的效果,包括带有重力的swipe或者是类似新的信息app中的带有弹簧效果聊天泡泡等。如果您还不太了解iOS7中信息app的效果,这里有一张gif图可以帮您大概了解一下:这次笔记的内容主要就是实现一个这样的效果。为了避免重复造轮子,我对这个效果进行了一些简单的封装,并连同这篇笔记的demo一起扔在了Github上,有需要的童鞋可以到这里自取。iOS7的SDK中Apple最大的野心其实是想用SpriteKit来结束iOS平台游戏开发(至少是2D游戏开发)的乱战,统一游戏开发的方式并建立良性社区。而UIKit Dynamics,个人猜测Apple在花费力气为SpriteKit开发了物理引擎的同时,发现在UIKit中也可以使用,并能得到不错的效果,于是顺便革新了一下设计理念,在UI设计中引入了不少物理的概念。在iOS系统中,最为典型的应用是锁屏界面打开相机时中途放弃后的重力下坠+反弹的效果,另一个就是信息应用中的加入弹性的消息列表了。弹性列表在我自己上手试过以后觉得表现形式确实很生动,可以消除原来列表那种冷冰冰的感觉,是有可能在今后的设计中被大量使用的,因此决定学上一学。1首先我们需要知道要如何实现这样一种效果,我们会用到哪些东西。毋庸置疑,如果不使用UIKit Dynamics的话,自己从头开始来完成会是一件非常费力的事情,你可能需要实现一套位置计算和物理模拟来使效果看起来真实滑润。而UIKit Dynamics中已经给我们提供了现成的弹簧效果,可以用UIAttachmentBehavior进行实现。另外,在说到弹性效果的时候,我们其实是在描述一个列表中的各个cell之间的关系,对于传统的UITableView来说,描述UITableViewCell之间的关系是比较复杂的(因为Apple已经把绝大多数工作做了,包括计算cell位置和位移等。使用越简单,定制就会越麻烦在绝大多数情况下都是真理)。而UICollectionView则通过layout来完成cell之间位置关系的描述,给了开发者较大的空间来实现布局。另外,UIKit Dynamics为UICollectionView做了很多方便的Catagory,可以很容易地“指导”UICollectionView利用加入物理特性计算后的结果,在实现弹性效果的时候,UICollectionView是我们不二的选择。这部分没什么可以多说的,现在我们有一个标准的FlowLayout的UICollectionView了。通过使用UICollectionViewFlowLayout的子类来作为开始的layout,我们可以节省下所有的初始cell位置计算的代码,在上面代码的情况下,这个collectionView的表现和一个普通的tableView并没有太大不同。接下来我们着重来看看要如何实现弹性的layout。对于弹性效果,我们需要的是连接一个item和一个锚点间弹性连接的UIAttachmentBehavior,并能在滚动时设置新的锚点位置。我们在scroll的时候,只要使用UIKit Dynamics的计算结果,替代掉原来的位置更新计算(其实就是简单的scrollView的contentOffset的改变),就可以模拟出弹性的效果了。将在CollectionView进行排版的时候被调用。首先当然是call一下super的prepareLayout,你肯定不会想要全都要自己进行设置的。接下来,如果是第一次调用这个方法的话,先初始化一个UIDynamicAnimator实例,来负责之后的动画效果。iOS7 SDK中,UIDynamicAnimator类专门有一个针对UICollectionView的Category,以使UICollectionView能够轻易地利用设定新的Behavior锚点值呢?理论上来说当然是可以的,但是如果这样的话我们大概就不得不面临着将刚才的layout实例设置为collectionView的delegate这样一个事实。但是我们都知道layout应该做的事情是给collectionView提供必要的布局信息,而不应该负责去处理它的委托事件。处理collectionView的回调更恰当地应该由处于collectionView的controller层级的类来完成,而不应该由一个给collectionView提供数据和信息的类来响应每次layout的bounds发生变化的时候,collectionView都会询问这个方法是否需要为这个新的边界和更新layout。一般情况下只要layout没有根据边界不同而发生变化的话,这个方法直接不做处理地返回NO,表示保持现在的layout即可,而每次bounds改变时这个方法都会被调用的特点正好可以满足我们更新锚点的需求,因此我们可以在这里面完成锚点的更新。帮助很大!但是看完之后还有一个问题,就是ios7的message和evernote app里面的弹簧效果是停的非常快,不会在你松手了之后还要震动一会儿。我本来以为是damping和frequency参数调节的