本文转载自http://tech.glowing.com/cn/
如有侵犯,立马删除
原文链接:实现iOS 9 Task Switcher动画
##升级到iOS 9以后,发现新的task switcher的动画蛮有趣的,于是就动手实现了下,最终效果如下~

思路
1    首先我们需要一个横向的scroll view,可以用UICollectionView,也可以自己实现一个。scroll view里每一页都是一张card,一屏5张card:
1 2 3 
  | |                        | |card card card card card| |                        | 
  | 
 
2    其次,我们需要在scrollViewDidScroll中判断每张card距离中心的距离,根据这个值来调整它的alpha,scale以及x轴的translation。
alpha:右边的card alpha都是1,左边的越靠左alpha越小
scale: 从左往右依次变大
translation:除了中间的card,所有的card都会右偏,而为了让中间card大部分都露出来,右边的card偏移需要比左边大
开工
我们可以自己实现一个横向无限滚动的scroll view, 具体可以参考:http://tech.glowing.com/cn/practice-in-uiscrollview/
在scrollViewDidScroll中,我们提供一个delegate方法,告诉使用者每一页距离中心的位置,以便apply各种transform到这个view上,delegate方法如下:
1 2 3 
  | @protocol InfiniteScrollViewDelegate \<NSObject\> - (void)updateView:(UIView *)view withProgress:(CGFloat)progress scrollDirection:(ScrollDirection)direction; @end 
  | 
 
说明一下progress的含义,如果一屏有5个visible views的话,那么它的值会从-2变化到2:
1 2 3 
  | |                   | |-2...-1...0...1...2| |                   | 
  | 
 
首先是alpha,中心右边的card alpha都是1,而左边的会越来越淡,所以我们可以这样写:
1 2 3 4 5 
  | if (progress \>= 0)    view.alpha = 1; } else  view.alpha = 1 - fabs(progress) * 0.2; } 
  | 
 
其次是scale,由左往右依次变大:
1 2 3 
  | CGAffineTransform transform = CGAffineTransformIdentity;   CGFloat scale = 1 + (progress) * 0.03;   transform = CGAffineTransformScale(transform, scale, scale); 
  | 
 
最后是x轴的translation,除了中间的card,所有的card都会往右偏,而为了让中间card大部分都露出来,右边的card偏移需要比左边大
1 2 3 4 5 6 7 
  | CGFloat translation = 0;   if (progress \> 0)    translation = fabs(progress) * SCREEN_WIDTH / 2.2; } else  translation = fabs(progress) * SCREEN_WIDTH / 15; } transform = CGAffineTransformTranslate(transform, translation, 0); 
  | 
 
完整的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 
  | -(void)updateView:(UIView *)view withProgress:(CGFloat)progress scrollDirection:(ScrollDirection)direction {          NSMutableArray *views = [[self.scrollView allViews] mutableCopy];     [views sortUsingComparator:^NSComparisonResult(UIView *view1, UIView *view2)      {         return view1.tag > view2.tag;     }];     for (UIView *view in views)      {         [view.superview bringSubviewToFront:view];     } if (progress >= 0)  {     view.alpha = 1; }  else  {     view.alpha = 1 - fabs(progress) * 0.2; } CGAffineTransform transform = CGAffineTransformIdentity;     CGFloat scale = 1 + (progress) * 0.03; transform = CGAffineTransformScale(transform, scale, scale); CGFloat translation = 0; if (progress > 0)  {     translation = fabs(progress) * SCREEN_WIDTH / 2.2; }  else {     translation = fabs(progress) * SCREEN_WIDTH / 15; } transform = CGAffineTransformTranslate(transform, translation, 0); view.transform = transform; } 
  | 
 
最后是完整的demo代码:https://github.com/Glow-Inc/TaskSwitcherDemo