UIScrollView視覺差動畫
前言:看到鳳凰新聞 頭條欄目的編輯推薦新聞是這個效果,覺得不錯,就想著實現一下,以下就是我的實現過程,示例程式碼請看這兒→ ScrollView-.git" rel="nofollow,noindex">UIScrollView視覺差動畫 。

一、首先實現一個基本的圖集瀏覽功能,如下圖
該功能太基礎,直接先貼一個UIScrollView,然後幾個UIImageView啪啪啪往UIScrollView上面一扔.......Over,不在此囉嗦咯。

二、分析動畫效果,提出解決方案
注意:這裡的left和right是區分拖動中可見的兩個檢視。
-
1. 分析效果
由總效果圖和第一步的普通的瀏覽效果圖對比可以看出,在拖拽過程中,第一步中的普通效果圖是圖片之間首尾相連,當前( left )的圖片尾部連線下一個( right )的圖片首部;而目標總效果圖中的是圖片之間首首相連,尾尾相連,且滑動過程中,當前可見的圖片有漸進的裁剪效果;前者就像是平鋪在一起的一行書,一塊兒左右平移,而後者就像是翻書時看到的效果,當前頁***left***內容由邊到內逐漸消失,而下一頁***right***內容由邊緣到裡逐漸顯示。
-
2. 解決思路
通過效果分析對比可知,我們需要在第一步的基礎上把每一個圖片檢視ImageView包裝在***WSLAnimationView***裡,讓WSLAnimationView去處理ImageView的動畫效果,那問題來了,我們怎麼處理呢?
- 我們可以在拖拽過程中相對應的改變 right/left 圖片在父檢視WSLAnimationView上的X座標,把***right***圖片的座標位置放到***相對***於***left***圖片的** 正下/偏右方 位置,然後隨著拖拽滑動逐漸改變 right以及left 圖片的相對位置X座標,直至復位,回到它們在WSLAnimationView上的初始位置X=0,超出父檢視的部分裁剪掉,也是設定WSLAnimationView物件的clipsToBounds = YES。

三、程式碼實現
-
1. 首先建立一個承載UIImageView的容器WSLAnimationView,用於漸進動畫裁剪效果。
@interface WSLAnimationView () @property (nonatomic, strong) UIImageView * imageView; /** imageView的橫座標 用於拖拽過程中的動畫 */ @property (nonatomic, assign) CGFloat contentX; @end @implementation WSLAnimationView - (instancetype)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { self.clipsToBounds = YES; _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; [self addSubview:_imageView]; } return self; } - (void)setContentX:(CGFloat)contentX{ _contentX = contentX; _imageView.frame = CGRectMake(contentX, 0, self.frame.size.width, self.frame.size.height); } 複製程式碼
-
2. 在拖拽滑動過程中進行動畫處理
#define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width) #define SCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height) #define SCROLLVIEW_WIDTH SCREEN_WIDTH #define BaseTag 10 /** 動畫偏移量 是指rightView相對於leftView的偏移量 */ #define AnimationOffset 100 - (void)scrollViewDidScroll:(UIScrollView *)scrollView{ CGFloat x = scrollView.contentOffset.x; NSInteger leftIndex = x/SCROLLVIEW_WIDTH; //這裡的left和right是區分拖動中可見的兩個檢視 WSLAnimationView * leftView = [scrollView viewWithTag:(leftIndex + BaseTag)]; WSLAnimationView * rightView = [scrollView viewWithTag:(leftIndex + 1 + BaseTag)]; leftView.contentX = ((SCROLLVIEW_WIDTH - AnimationOffset) + (x - ((leftIndex + 1) * SCROLLVIEW_WIDTH))/SCROLLVIEW_WIDTH * (SCROLLVIEW_WIDTH - AnimationOffset)); rightView.contentX = -(SCROLLVIEW_WIDTH - AnimationOffset) + (x - (leftIndex * SCROLLVIEW_WIDTH))/SCROLLVIEW_WIDTH * (SCROLLVIEW_WIDTH - AnimationOffset); } 複製程式碼
-
3. 程式碼處理邏輯說明
動畫偏移量AnimationOffset = 0 時 即***right***圖片的座標位置放到***相對***於***left***圖片的***正下方***位置,此時的效果如下圖所示;當AnimationOffset > 0 時就會出現目標總效果圖了。

剛向左拖拽時的leftView和rightView檢視結構示意圖如下所示, 那麼拖拽中,逐漸移動復位rightView上的RightImage的X座標: rightView.contentX = 需要移動距離長度 - 移動百分比 * 需要移動距離長度 ; leftView.contentX 和這個類似,交由小夥伴們去思考。
需要移動距離長度 =SCROLLVIEW_WIDTH - AnimationOffset; 移動百分比 = 拖拽距離 /一頁寬度即螢幕寬度 拖拽距離 =(偏移量X - leftView橫座標); 偏移量X = scrollView.contentOffset.x; leftIndex = 偏移量X/SCROLLVIEW_WIDTH; leftView橫座標 = leftIndex * SCROLLVIEW_WIDTH; 複製程式碼

以上就是我實現這個效果的過程,示例程式碼請看這兒 UIScrollView視覺差動畫 ;如果小夥伴們有其他的實現方法,歡迎再此留言交流:blush::blush::grinning::grinning:

如果需要跟我交流的話: ※ Github: github.com/wsl2ls ※ 個人部落格:wsl2ls.github.io ※ 簡書: www.jianshu.com/u/e15d1f644… ※ 微信公眾號:iOS2679114653 ※ QQ:1685527540