本文轉(zhuǎn)載自http://tech.glowing.com/cn/
如有侵犯,立馬刪除
原文鏈接:實(shí)現(xiàn)iOS 9 Task Switcher動畫
升級到iOS 9以后,發(fā)現(xiàn)新的task switcher的動畫蠻有趣的伦泥,于是就動手實(shí)現(xiàn)了下,最終效果如下~
思路
1 首先我們需要一個橫向的scroll view,可以用UICollectionView,也可以自己實(shí)現(xiàn)一個沈条。scroll view里每一頁都是一張card需忿,一屏5張card:
| |
|c(diǎn)ard card card card card|
| |
2 其次诅炉,我們需要在scrollViewDidScroll中判斷每張card距離中心的距離,根據(jù)這個值來調(diào)整它的alpha屋厘,scale以及x軸的translation涕烧。
alpha:右邊的card alpha都是1,左邊的越靠左alpha越小
scale: 從左往右依次變大
translation:除了中間的card汗洒,所有的card都會右偏议纯,而為了讓中間card大部分都露出來,右邊的card偏移需要比左邊大
開工
1. 橫向滾動的scroll view
我們可以自己實(shí)現(xiàn)一個橫向無限滾動的scroll view, 具體可以參考:http://tech.glowing.com/cn/practice-in-uiscrollview/
在scrollViewDidScroll中溢谤,我們提供一個delegate方法瞻凤,告訴使用者每一頁距離中心的位置,以便apply各種transform到這個view上世杀,delegate方法如下:
@protocol InfiniteScrollViewDelegate \<NSObject\>
- (void)updateView:(UIView *)view withProgress:(CGFloat)progress scrollDirection:(ScrollDirection)direction;
@end
說明一下progress的含義阀参,如果一屏有5個visible views的話,那么它的值會從-2變化到2:
| |
|-2...-1...0...1...2|
| |
2. 根據(jù)每一頁的位置來設(shè)置它的transform
首先是alpha瞻坝,中心右邊的card alpha都是1蛛壳,而左邊的會越來越淡,所以我們可以這樣寫:
if (progress \>= 0)
view.alpha = 1;
} else
view.alpha = 1 - fabs(progress) * 0.2;
}
其次是scale所刀,由左往右依次變大:
CGAffineTransform transform = CGAffineTransformIdentity;
CGFloat scale = 1 + (progress) * 0.03;
transform = CGAffineTransformScale(transform, scale, scale);
最后是x軸的translation衙荐,除了中間的card,所有的card都會往右偏浮创,而為了讓中間card大部分都露出來忧吟,右邊的card偏移需要比左邊大
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);
完整的實(shí)現(xiàn):
-(void)updateView:(UIView *)view withProgress:(CGFloat)progress scrollDirection:(ScrollDirection)direction
{
// adjust z-index of each views
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];
}
// alpha
if (progress >= 0)
{
view.alpha = 1;
}
else
{
view.alpha = 1 - fabs(progress) * 0.2;
}
CGAffineTransform transform = CGAffineTransformIdentity;
// scale
CGFloat scale = 1 + (progress) * 0.03;
transform = CGAffineTransformScale(transform, scale, scale);
// translation
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