1. 程式人生 > >iOS轉場動畫之微信朋友圈圖片檢視器

iOS轉場動畫之微信朋友圈圖片檢視器

前言

什麼是轉場動畫呢?顧名思義,就是切換介面所用的動畫效果。本文主要介紹的是modal的效果。當我們使用modal的時候,只需要使用 presentViewController:animated:completiondismissViewControllerAnimated:completion 即可實現介面的彈出和消失,但是這樣的動畫過於單調,只是簡單的彈出消失,沒有’藝術性’,嘿嘿嘿,如果我們想要炫酷複雜的動畫,那就只有自定義動畫了。

modal設定自定義轉場步驟

1.設定屬性和代理

屬性

當我們使用普通的modal進行轉場的時候,是這樣的

//建立要跳轉的控制器
CLHPhotoBrowserViewController *photoVC = [[CLHPhotoBrowserViewController alloc] init]; //跳轉控制器 [self.window.rootViewController presentViewController:photoVC animated:YES completion:nil];

但是如果我們要自定義modal轉場動畫,那麼需要設定ViewController的modalPresentationStyle屬性為UIModalPresentationCustom.即自定義狀態,因為系統預設的屬性為UIModalPresentationFullScreen,即充滿螢幕.

photoVC.modalPresentationStyle = UIModalPresentationCustom;

代理

從iOS7之後,蘋果推出了真正可以實現轉場動畫的API,這才讓我們有了那麼多酷炫的介面效果和動畫,轉場呢,又分為互動式轉場和非互動式轉場,本文主要講解非互動式轉場,因為這種轉場可以讓我們完全控制轉場所利用的介面和動畫。

自定義轉場其實也很簡單,只是實現一個協議而已,如果我們使用modal進行轉場,那麼我們必須設定我們要跳轉控制器的transitioningDelegate,而要成為跳轉控制器的代理,需要遵守UIViewControllerTransitioningDelegate

協議.為了防止程式碼量太多而導致不好管理,所以說我一般自定義一個類,來管理轉場動畫,這裡我們使用一個CLHPhotoBrowserAnimator類來管理轉場動畫.

//將自定義類設定為轉場代理
photoVC.transitioningDelegate = self.animator;

2.實現代理方法

UIViewControllerTransitioningDelegate

UIViewControllerTransitioningDelegate 中,我們主要使用兩個方法.

  • 彈出介面的回撥方法
-(id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{
    return self;
}
  • 消失介面的回撥方法
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{
    return self;
}

UIViewControllerAnimatedTransitioning

從上面的回撥方法中我們發現,返回的物件必須遵守UIViewControllerAnimatedTransitioning 協議,因為上面的協議UIViewControllerTransitioningDelegate 是來設定動畫的執行者的,而UIViewControllerAnimatedTransitioning 才是設定動畫的,所以說,我們自定義的CLHPhotoBrowserAnimator必須遵守此協議,並實現其代理方法.

  • 設定轉場動畫的執行時間
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
    return 0.5;
}
  • 轉場上下文,這裡可以用來提供轉場動畫過程中兩個控制器的資訊
    因為我們自定義了動畫的執行,所以說系統無法自動呼叫這些方法,所以說我們可以設定一個BOOL屬性presented來表示控制器的彈出和消失
    @property(nonatomic, assign, getter=isPresented) BOOL presented;
    我們要設定的轉場動畫有可能很複雜,所以說,我們可以將彈出和消失動畫抽出兩個方法,並將轉場上下文傳過去,這樣程式碼看起來更好看,而且增加維護性.然後我們就可以在自定義的彈出動畫方法中設定動畫了,這個時候就需要你奇妙的腦洞了.
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
    if(self.isPresented){
        //呼叫自定義彈出動畫
        [self animationForPresentView:transitionContext];
    } else{
        //呼叫自定義消失動畫
        [self animationForDismissView:transitionContext];
    }
}

實戰之微信朋友圈圖片檢視器

實現效果

動畫分析

我們發現如果在微信點選檢視圖片,那個圖片是從小到大,然後充滿螢幕的(如果可以充滿螢幕的話),如果再次點選圖片,圖片由全屏又變回它應該在的位置,所以說關鍵點就在於在進行轉場的時候我們要拿到圖片放大之前的位置和放大之後的位置還有當前圖片,在消失的時候我們要拿到圖片的資訊和當前所瀏覽圖片縮小後應該處於的位置。
分析之後,我們一步一步來

基本實現框架

總體設計我們使用代理的設計模式,所以在自定義類CLHPhotoBrowserAnimator中設定兩個協議,一個是轉場協議photoBrowserAnimatorDelegate 一個是消失協議photoBrowserAnimatorDismissDelegate 首先我們先看一下轉場協議。

  • 轉場協議
    當我們點選圖片進行轉場的時候,需要獲取圖片當前所在的位置和放大後所在的位置還有當前圖片,所以說我們在協議中定義三個方法來實現這些功能:
@protocol photoBrowserAnimatorDelegate <NSObject>
//獲取開始位置
- (CGRect)startRect:(NSInteger)index;
//獲取放大後的位置
- (CGRect)endRect:(NSInteger)index;
//獲取當前圖片
- (UIImageView *)locImageView:(NSInteger)index;
@end
  • 消失協議
    當圖片消失的時候,因為我們可能會翻動圖片,所以說,我們需要知道當前圖片在縮小後的位置和當前圖片的資訊,所以我們在協議中定義兩個方法來實現這些功能:
@protocol photoBrowserAnimatorDismissDelegate <NSObject>
//獲取當前圖片的下標
- (NSInteger)indexForDismissView;
//獲取當前圖片
- (UIImageView *)imageViewForDismissView;
@end

當寫好協議之後,當我們設定自定義轉場的時候,就可以將給自定義類CLHPhotoBrowserAnimator 設定兩種代理。

轉場協議

如何來拿到圖片放大之前的位置呢?從哪裡拿到呢?下面我們一一解答

1.從哪裡拿?

整個朋友圈我是用一個UITableView來實現的,tableView中一條動態又是一個cell,在cell中我設定了一個佔位View(CLHWerChatPhotoView)來放置圖片(請忽略我當時手速過快導致拼寫錯誤 = =,然後在這個View中新增圖片,當我們點選了圖片的時候,我們也是在這個View中作出反應,所以說我們轉場所需要的資訊可以從這個View中拿,但是首先這個類必須先遵守轉場協議photoBrowserAnimatorDelegate

//設定轉場協議
self.animator.animationDelegate = self;

2.如何獲得

  • 獲取開始位置
    在佔位的View中新增圖片的時候,我給每一個圖片加了一個tag,然後增加了點選手勢,所以說,每當點選了圖片,我可以將tag當做下標傳過去,然後根據下標找到圖片,得到圖片在整個視窗的位置。
- (CGRect)startRect:(NSInteger)index{
    UIImageView *imageView = nil;
    for(NSInteger i = 0; i < self.subviews.count; i++){
        if([self.subviews[i] isKindOfClass:[UIImageView class]]){//檢驗是否為圖片
            UIImageView *view = self.subviews[i];
            if(view.tag == index){//查詢點選的圖片
                imageView = view;
            }
        }
    }
    //返回當前的圖片在視窗的位置
    return [self convertRect:imageView.frame toView:[UIApplication sharedApplication].keyWindow];
}
  • 獲取結束位置
    結束位置即是當前圖片在新的控制器中的位置,這個就好求了,只要等比例縮放就行了,這裡就不詳細解釋了。
- (CGRect)endRect:(NSInteger)index{
    //拿到當前下標所對應的圖片
    UIImage *image = [UIImage imageNamed:self.photoArray[index]];
    //計算imageView的frame
    CGFloat x = 0;
    CGFloat width = screenW;
    CGFloat height = width / image.size.width * image.size.height;
    CGFloat y = 0;
    if(height < screenH){
        y = (screenH - height) * 0.5;
    }
    return CGRectMake(x, y, width, height);
}
  • 獲取當前的圖片資訊
    這個也是根據下標獲取的,只要返回一個對應的UIImageView即可
- (UIImageView *)locImageView:(NSInteger)index{
    UIImageView *imageView = [[UIImageView alloc] init];
    UIImage *image = [UIImage imageNamed:self.photoArray[index]];
    imageView.image = image;
    imageView.contentMode = UIViewContentModeScaleToFill;
    imageView.clipsToBounds = YES;
    return imageView;
}

消失協議

消失動畫同樣需要當前圖片所處位置和下標,還有縮小後的位置,注意兩個問題,一個是從哪裡拿?二是怎麼拿?

1.從哪裡拿

我們自定義一個圖片檢視器的控制器CLHPhotoBrowserViewController 來顯示放大後的圖片,而且放大後的滾動等一系列動作都是在其中完成的,所以說動畫的消失代理設定為CLHPhotoBrowserViewController 再合適不過了.

self.animator.animationDismissDelegate = photoVC;

2.怎麼拿?

  • 獲取當前圖片的下標
    這個比較簡單了,因為我實現朋友圈檢視器是使用UICollectionView實現的,所以說每個cell的大小都是整個螢幕,所以說當前顯示的圖片的cell的下標即為圖片的下標
- (NSInteger)indexForDismissView{
    //獲取當前顯示在螢幕上的cell
    CLHPhotoCell *cell = [_collectionView visibleCells].firstObject;
    return [_collectionView indexPathForCell:cell].row;
}
  • 獲取當前圖片
    這個當然也是小菜一碟了
- (UIImageView *)imageViewForDismissView{
    UIImageView *imageView = [[UIImageView alloc] init];
    CLHPhotoCell *cell = [_collectionView visibleCells].firstObject;
    imageView.image = cell.imageView.image;
    imageView.frame = cell.imageView.frame;
    imageView.contentMode = UIViewContentModeScaleToFill;
    imageView.clipsToBounds = YES;
    return imageView;

}

動畫實現

彈出動畫

我們可以通過轉場上下文的viewForKey來獲取到轉場的源檢視和目標檢視

//自定義彈出動畫
- (void)animationForPresentView:(id<UIViewControllerContextTransitioning>)transitionContext{
    //獲取要彈出的View
    UIView *presentView = [transitionContext viewForKey:UITransitionContextToViewKey];
    //將執行的View新增到上下文的containerView
    [transitionContext.containerView addSubview:presentView];

    //獲取開始尺寸和結束尺寸
    CGRect startRect = [self.animationDelegate startRect:self.index];
    CGRect endRect = [self.animationDelegate endRect:self.index];
    UIImageView *imageView = [self.animationDelegate locImageView:self.index];
    //將圖片新增到上下文的containerView
    [transitionContext.containerView addSubview:imageView];
    //設定初始frame
    imageView.frame = startRect;

    presentView.alpha = 0;
    transitionContext.containerView.backgroundColor = [UIColor blackColor];
    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        //設定圖片的結束frame
        imageView.frame = endRect;
    }completion:^(BOOL finished) {
        presentView.alpha = 1.0;
        [imageView removeFromSuperview];
        transitionContext.containerView.backgroundColor = [UIColor clearColor];
        //一定要告訴轉場上下文動畫完成了
        [transitionContext completeTransition:YES];
    }];
}

消失動畫

//自定義消失動畫
- (void)animationForDismissView:(id<UIViewControllerContextTransitioning>)transitionContext{
    //獲取要消失的view
    UIView *dismissView = [transitionContext viewForKey:UITransitionContextFromViewKey];
    [dismissView removeFromSuperview];
    //獲取要消失的圖片
    UIImageView *imageView = [self.animationDismissDelegate imageViewForDismissView];
    [transitionContext.containerView addSubview:imageView];
    //獲取要消失的圖片的下標
    NSInteger index = [self.animationDismissDelegate indexForDismissView];

    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        //以剛開始彈出的初始位置為動畫後圖片的frame
        imageView.frame = [self.animationDelegate startRect:index];
    } completion:^(BOOL finished) {
        //告訴轉場上下文動畫完成
        [transitionContext completeTransition:YES];
    }];
}

modal自定義轉場動畫之微信朋友圈圖片檢視器的實戰關鍵思路就是這些啦。

總結

在學習了轉場動畫之後,是不是感覺很簡單呢?以後我們就可以發揮自己神奇的腦洞來實現各種各樣酷炫的動畫效果了,有什麼好的動畫可以通知我哦,我會mark下來慢慢欣賞,謝謝。

那麼就先說到這裡啦,有疑問和不足請務必要通知我!!!同時也歡迎大家關注和頂一下!嘿嘿嘿!

歡迎來到我的部落格,我是AnICoo1,我喂自己袋鹽
有錯誤請評論指出或聯絡我,不勝感激!
個人郵箱:[email protected]
轉載請註明出處,畢竟寫了這麼多也不容易,謝謝!

相關推薦

iOS動畫朋友圖片檢視

前言 什麼是轉場動畫呢?顧名思義,就是切換介面所用的動畫效果。本文主要介紹的是modal的效果。當我們使用modal的時候,只需要使用 presentViewController:animated:completion 和 dismissViewControl

移動web HTML5使用photoswipe模仿朋友圖片放大瀏覽

默認 html5 ace 模仿 響應式 觸摸手勢 朋友圈 int 放大 http://www.cnblogs.com/theroad/p/5397229.html 使用js框架是PhotoSwipe。 PhotoSwipe是一個圖片放大插件,兼容pc和移動端,經歷過多個版本

CSS——朋友圖片樣式實現方法

spl absolut position url head density pad OS use <!DOCTYPE html> <html lang="en"> <head> <meta ch

canvas圖片文字自動合成---朋友圖片分享

canvas-Synthetic-picture canvas圖片合成,支援右鍵另存為 一、合成內容 1.圖片 背景圖 專屬二維碼 使用者頭像(圓形) 2.使用者名稱 二、專案地址 https://github.com/Sta

模仿朋友 圖片瀏覽 js javascript 支援圖片預覽,滑動切換,雙指縮放,圖片快取

previewImage-mobile 仿微信js-sdk wx.previewImage javascript實現,支援圖片預覽,滑動切換,雙指縮放,圖片快取; it is a plugin previewImage for mobile html5

previewImage.js實現類似朋友圖片預覽功能

由於公司專案需要一個類似圖片預覽的效果就是圖片可以滑動切換,雙指縮放 公司封裝的存在相容性問題,在安卓上圖片放大後圖片上的字就模糊了,就在網上找到了previewImage.js 引用 previewImage.js 到你的專案中<script src="dist/p

仿朋友圖片點選放大效果

這兩天寫了個小專案,其中用到了點選一組圖片中的一張可以檢視它的放大版,用手向左滑動能看到下一張的這組圖片中的第二張的放大版。。。依次類推,單擊放大版的圖片實現關閉效果,對於js能力不太好的我只能找度娘,然後就發現了photoswiper.js,不得不說真的好用,

iOS朋友和掃一掃頁面(已廢棄)

// 是否支援微信 NSURL * myURL_APP_A = [NSURL URLWithString:@"weixin://"]; if ([[UIApplication sharedApplication] canOpenURL:myURL

Py:數據挖掘對個人朋友好友的性別、區域、昵稱、簽名息進行情感分析——Jason niu

簽名信息 col ram gif -s post 區域 ons AR #Py:數據挖掘之對微信朋友圈好友的性別、區域、昵稱、簽名信息進行情感分析——Jason niu import os import re import csv import time import jso

朋友開啟下載連結跳到預設瀏覽器的程式碼

微信被認為是目前最具營銷價值的營銷渠道之一,原因很簡單,微信是目前超高活躍度的app穩穩第一名,但是在微信中點選app下載連結,都是無法下載app的。因為騰訊為了自身利益,遮蔽了其他app直接在微信中下載。我們要怎麼解決這個問題呢? 解決方式: 微信中開啟連結,自動開啟外部瀏覽器開啟頁面 微信中點選或開啟

iOS塗色塗鴉效果、Swift仿喜馬拉雅FM、抽屜動畫、拖拽頭像、標籤選擇等原始碼

iOS精選原始碼 iOS優質部落格 WKWebView是蘋果在iOS 8之後推出的框架WebKit中的瀏覽器控制元件, 其載入速度比UIWebView快了許多, 但記憶體佔用率卻下降很多, 也解決了載入網頁時的記憶體洩露問題. 現在的專

安卓專案實戰仿朋友的九宮格自定義控制元件

效果圖 圖片展示形式 1、當只有1張圖時,可以自己定製圖片寬高,也可以使用預設九宮格的寬高; 2、當只有4張圖時,以2*2的方式顯示; 3、除以上兩種情況下,都是按照3列方式顯示,但這時有一些細節: a、如果只有9張圖,當然是以3*3的方式顯示;

Android仿朋友九宮格圖片展示自定義控制元件,支援縮放動畫~

一直對微信朋友圈九宮格圖片顯示控制元件比較好奇,找到一篇介紹相關騷操作的部落格 部落格雖好但是不夠完美,缺少點選圖片預覽頁面和縮放動畫,作為一個不斷追求完美主義的人,我想把這個控制元件結合到專案中而不是單純作為一個控制元件。 下面是我的實現效果圖: (

iOS:仿朋友程式碼

仿WeChat朋友圈的介面效果,程式碼整潔易讀,靜態頁面,無網路互動。裡面的功能並沒有全部完善,可以根據自己的需求去補充一下。 程式碼結構 每個類檔案中都有詳細的備註和註釋,模組劃分和流程都還蠻清晰的,這裡就不贅述了,讀程式碼更直接一些。 檢視結構 Cell的

試用友盟SDK實現Android分享朋友

社會 mis gettext 視頻 blog test cte widget mod 社會化分享是眼下必學且火熱的功能。之前有寫第三方登錄,那僅僅是社會化分享的一部分。今天來玩玩分享微信朋友圈。 為了方便操作,還是依照步驟寫。 一,註冊 註冊應用已經在

朋友字體顏色怎麽改變?

在微信朋友圈中,有時候我們會看到有些朋友發了帶顏色字體的文字,看起來相當好看,那麽這是怎麽做到的呢?微信朋友圈字體顏色怎麽改變?今天小編就為大家地阿萊了微信朋友圈怎麽發有顏色的字體的相關教程,想知道就一起往下看吧。 微信朋友圈怎麽發有顏色的字體通過很簡單的字符拼湊而成,統一格式為:字體。

Android 修改源碼自定義SwipeRefreshLayout樣式——高仿朋友下拉刷新

樣式 post and 微信 修改 size roi 自定義 details 修改源碼自定義SwipeRefreshLayout樣式——高仿微信朋友圈下拉刷新Android 修改源碼自定義SwipeRefreshLayout樣式——高仿微信朋友圈下拉

apiCloud 三方分享,好友分享,朋友分享,QQ分享,博分享

-s -a nbsp 分享 ocs 配置 博客 微信朋友圈 icloud 首先查看我的這篇有關三方登錄的博客,地址是http://www.cnblogs.com/gqx-html/p/8303567.html,配置完三方數據後可以從上一篇文章中的鏈接跳轉到各個登錄查看api

HTML5仿聊天界面、朋友實例

很好 order 分享圖片 ext mount case 天使 inf 仿微信 這幾天使用H5開發了一個仿微信聊天前端界面,尤其微信底部編輯器那塊處理的很好,使用HTML5來開發,雖說功能效果並沒有微信那麽全,但是也相當不錯了,可以發送消息、表情,發送的消息自動回滾定位到底

怎樣屏蔽朋友視頻?局域網如何禁止員工看朋友視頻?

網絡管理上班時間刷刷朋友圈,一眨眼半小時就過去了。不但會影響工作效率,而且朋友圈的視頻會占用大量的帶寬。所以對企業管理人員來說,很多時候需要禁止員工在工作時段刷朋友圈。但是行政手段要和技術手段配合,才可以發揮真正的作用。本文將介紹如何用WFilter NGF(WSG網關)來禁止朋友圈的視頻。首先,應該設置什麽