1. 程式人生 > >iOS開發之窺探UICollectionViewController(五):一款炫酷的圖片瀏覽元件

iOS開發之窺探UICollectionViewController(五):一款炫酷的圖片瀏覽元件

本篇部落格應該算的上CollectionView的高階應用了,從到今天的(五),可謂是由淺入深的窺探了一下UICollectionView的用法,這些用法不僅包括SDK中自帶的流式佈局(UICollectionViewDelegateFlowLayout)而且介紹瞭如何根據你的需求去自定義屬於你自己的CollectionView。自定義的CollectionView可謂是非常靈活,其靈活性也決定了其功能的強大。CollectionView的自定義就是其Cell高度可定製的屬性,通過對Cell賦值不同的屬性來達到自定義的目的。

在上篇部落格中,通過自定義的CollectionView建立了一個可定製的自定義瀑布流,效果還是蠻ok的。本篇部落格是使用自定義CollectionView的另一個例項,自定義CollectionView的方式和上一篇是一致的,都是重寫UICollectionViewLayout相應的方法,然後再通過委託回撥來設定佈局的引數。自定義CollectionView的思路是一樣的,只是具體的實現方式不同。學習麼,要學會舉一反三,希望大家能通過這兩篇自定義CollectionView的部落格來寫出屬於你自己的自定義效果。

一.效果展示

廢話少說,進入今天部落格的主題,下方就是今天部落格中Demo的執行效果。雖然執行效果做成gif丟幀了,看起來有些卡,不過跑起來還是比較流暢的。切換圖片時進行一個360度的旋轉,並且修改Cell的層級,當前顯示的圖片層級最高。並且移動時,如果要顯示的圖片不在螢幕中央就做一個位置矯正。點選圖片時,使用仿射變換使其放大,再點選使其縮小。接下來將會詳細的介紹其實現方案。

二.該自定義佈局的使用方式

我們先看一下該自定義佈局是如何使用的,然後再通過使用方式來逐步介紹它是如何實現的。這也是一個由淺入深的過程,因為用起來要比做起了更容易。比如開汽車容易,造汽車可就麻煩多了。所以在本篇部落格的第二部分,將要介紹如何去使用該自定義元件。

其實所有CollectionView的自定義佈局的使用方式都是一樣的,分為以下幾步:

1.為我們的CollectionView指定該佈局,本篇部落格的CollectionView是通過Storyboard來實現的,所以我們可以通過Storyboard來指定自定義的佈局檔案,如果你是使用純程式碼方式,可以在CollectionView例項化時來指定所需的佈局。下方是使用Storyboard來指定的佈局檔案,需要把Layout選項調到Custom下,然後下方的Class選項就是你要關聯的自定義佈局檔案,具體如下所示。程式碼的就在此不做贅述了,網上一抓一大把。

2.給Storyboard上的CollectionViewController關聯一個類,然後我們就可以使用自定義的佈局了。獲取指定的自定義佈局物件,然後指定委託代理物件,如下所示:

Objective-C
123456 -(void)viewDidLoad{[superviewDidLoad];_customeLayout=(CustomTransformCollecionLayout*)self.collectionViewLayout;_customeLayout.layoutDelegate=self;}

3.除了實現CollectionView的DataSource和Delegate, 我們還需實現佈局的代理方法,該自定義佈局要實現的代理方法如下。第一個是設定Cell的大小,也就是寬高。第二個是設定Cell間的邊距。

Objective-C
1234567891011 #pragma mark -(CGSize)itemSizeWithCollectionView:(UICollectionView*)collectionView                   collectionViewLayout:(CustomTransformCollecionLayout*)collectionViewLayout{returnCGSizeMake(200,200);}-(CGFloat)marginSizeWithCollectionView:(UICollectionView*)collectionView                      collectionViewLayout:(CustomTransformCollecionLayout*)collectionViewLayout{return10.0f;}

4.點選Cell放大和縮小是在UICollectionViewDataSource中點選Cell的代理方法中做的,在此就不做贅述了,詳見GitHub上分享的連結。

三. 如何實現

上面介紹瞭如何去使用該自定義元件,接下來就是“造車”的過程了。本篇部落格的第三部分介紹如何去實現這個自定義佈局。

1. CustomTransformCollecionLayout標頭檔案中的程式碼如下所示,該檔案中定義了一個協議,協議中的方法就是在CollectionView中要實現的那兩個代理方法。這些代理方法提供了Cell的大小和邊距。該檔案的介面中定義了一個代理物件,當然為了強引用迴圈,該代理物件是weak型別的。

Objective-C
1234567891011121314151617181920212223242526272829303132333435 ////  CustomTransformCollecionLayout.h//  CustomTransformCollecionLayout////  Created by Mr.LuDashi on 15/9/24.//  Copyright (c) 2015年 ZeluLi. All rights reserved.//#import#define SCREEN_WIDTH [[UIScreen mainScreen] bounds].size.width#define SCREEN_HEIGHT [[UIScreen mainScreen] bounds].size.height@classCustomTransformCollecionLayout;@protocolCustomTransformCollecionLayoutDelegate/**  * 確定cell的大小  */-(CGSize) itemSizeWithCollectionView:(UICollectionView*)collectionView                  collectionViewLayout:(CustomTransformCollecionLayout*)collectionViewLayout;/**  * 確定cell的大小  */-(CGFloat) marginSizeWithCollectionView:(UICollectionView*)collectionView                  collectionViewLayout:(CustomTransformCollecionLayout*)collectionViewLayout;@end@interface CustomTransformCollecionLayout : UICollectionViewLayout@property(nonatomic,weak)idlayoutDelegate;@end

2.接下來介紹一下CustomTransformCollecionLayout實現檔案也就是.m中的程式碼,其中的延展中的屬性如下所示。numberOfSections:該引數代表著CollectionView的Section的個數。numberOfCellsInSection:代表著每個Section中Cell的個數。itemSize則是Cell的尺寸(寬高),該屬性的值是由佈局代理方法提供。itemMargin: 該屬性是Cell的邊距,它也是通過佈局的代理方法提供。itemsX: 用來儲存計算的每個Cell的X座標。

Objective-C
123456789101112131415161718 ////  CustomTransformCollecionLayout.m//  CustomTransformCollecionLayout////  Created by Mr.LuDashi on 15/9/24.//  Copyright (c) 2015年 ZeluLi. All rights reserved.//#import "CustomTransformCollecionLayout.h"@interfaceCustomTransformCollecionLayout()@property(nonatomic)NSIntegernumberOfSections;@property(nonatomic)NSIntegernumberOfCellsInSection;@property(nonatomic)CGSizeitemSize;@property(nonatomic)CGFloatitemMargin;18@property(nonatomic,strong)NSMutableArray*itemsX;@end

3. 在實現中我們需要重寫UICollectionViewLayout中相關的方法,需要重寫的方法如下:

(1). 預載入佈局方法, 該方法會在UICollectionView載入資料時執行一次,在該方法中負責呼叫一些初始化函式。具體如下所示。

Objective-C
12345678 #pragma mark -- UICollectionViewLayout 重寫的方法-(void)prepareLayout{[superprepareLayout];[selfinitData];[selfinitItemsX];}

(2).下面的方法會返回ContentSize, 說白一些,就是CollectionView滾動區域的大小。

Objective-C
1234567 /**  * 該方法返回CollectionView的ContentSize的大小  */-(CGSize)collectionViewContentSize{CGFloatwidth=_numberOfCellsInSection *(_itemSize.width+_itemMargin);returnCGSizeMake(width,SCREEN_HEIGHT);}

(3).下方的方法是為每個Cell繫結一個UICollectionViewLayoutAttributes物件,用來設定每個Cell的屬性。

Objective-C
1234567891011121314151617 /**   * 該方法為每個Cell繫結一個Layout屬性~   */-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect{NSMutableArray*array=[NSMutableArrayarray];//add cellsfor(inti=0;i){NSIndexPath*indexPath=[NSIndexPath indexPathForItem:i inSection:0];UICollectionViewLayoutAttributes*attributes=[self layoutAttributesForItemAtIndexPath:indexPath];[array addObject:attributes];}returnarray;}

(4).下方這個方法是比較重要的,重寫這個方法是為了為每個Cell設定不同的屬性值。其中transform的值是根據CollectionView的滾動偏移量來計算的,所以在滾動CollectionView時,Cell也會跟著旋轉。具體的實現方案在程式碼中添加了註釋,如下所示:

Objective-C
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 /**   * 為每個Cell設定attribute   */-(UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath*)indexPath{//獲取當前Cell的attributesUICollectionViewLayoutAttributes*attributes=[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];//獲取滑動的位移CGFloatcontentOffsetX=self.collectionView.contentOffset.x;//根據滑動的位移計算當前顯示的時第幾個CellNSIntegercurrentIndex=[self countIndexWithOffsetX: contentOffsetX];//獲取Cell的X座標CGFloatcenterX=[_itemsX[indexPath.row] floatValue];//計算Cell的Y座標CGFloatcenterY=SCREEN_HEIGHT/2;//設定Cell的center和size屬性attributes.center=CGPointMake(centerX,centerY);attributes.size=CGSizeMake(_itemSize.width,_itemSize.height);//計算當前偏移量(滑動後的位置 - 滑動前的位置)CGFloatanimationDistance=_itemSize.width+_itemMargin;CGFloatchange=contentOffsetX-currentIndex *animationDistance+SCREEN_WIDTH/-_itemSize.width/2;//做一個位置修正,因為當滑動過半時,currentIndex就會加一,就不是上次顯示的Cell的索引,所以要減去一做個修正if(change0){change=contentOffsetX-(currentIndex-1)*animationDistance+SCREEN_WIDTH/2-_itemSize.width/2;}if(currentIndex==0&contentOffsetX0){change=0;}//旋轉量CGFloattemp=M_PI*2*(change/(_itemSize.width+_itemMargin));//仿射變換 賦值attributes.transform=CGAffineTransformMakeRotation(temp);//把當前顯示的Cell的zIndex設定成較大的值if(currentIndex==indexPath.row){attributes.zIndex=1000;}else{attributes.zIndex=currentIndex;}returnattributes;

相關推薦

iOS開發窺探UICollectionViewController()圖片瀏覽元件

本篇部落格應該算的上CollectionView的高階應用了,從到今天的(五),可謂是由淺入深的窺探了一下UICollectionView的用法,這些用法不僅包括SDK中自帶的流式佈局(UICollectionViewDelegateFlowLayout)而且介紹瞭如何根據你的

iOS開發窺探UICollectionViewController(三) 使用UICollectionView自定義瀑布流

上篇部落格的例項是自帶的UICollectionViewDelegateFlowLayout佈局基礎上來做的Demo, 詳情請看《iOS開發之窺探UICollectionViewController(二) –詳解CollectionView各種回撥》。UICollectionV

iOS開發窺探UICollectionViewController(二) 詳解CollectionView各種回撥

UICollectionView的佈局是可以自己定義的,在這篇部落格中先在上篇部落格的基礎上進行擴充,我們先使用UICollectionViewFlowLayout,然後好好的介紹一下UICollectionView的一些回撥方法,主要包括UICollectionViewDat

iOS開發窺探UICollectionViewController() Ready Your CollectionViewController

之前用CollectionViewController只是皮毛,一些iOS從入門到精通的書上也是泛泛而談。這幾天好好的搞了搞蘋果的開發文件上CollectionViewController的內容,親身體驗了一下CollectionViewController的強大,之前一直認為

iOS開發窺探UICollectionViewController(四) --功能強大的自定義瀑布流

在上一篇部落格中,自定義瀑布流的列數,Cell的外邊距,Cell的最大以及最小高度是在我們的佈局檔案中是寫死的,換句話說也就是不可配置的。為了循序漸進,由淺入深呢,上篇部落格暫且那麼寫。不過那樣寫太過死板,本來使用起來比較靈活的自定義佈局,如果把其配置引數給寫死了,就相當於在籠

iOS開發效能除錯Instruments(

iOS效能除錯有很多方法,這裡講一下Xcode內建工具Instruments。 Instruments是一個官方提供的強大的效能除錯工具集。 instruments.png 1.Blank(空模板):建立一個空的模板,可以從Library庫中新增其他模板; 2.Act

iOS開發runtime(runtime除錯環境搭建

本系列部落格是本人的原始碼閱讀筆記,如果有iOS開發者在看runtime的,歡迎大家多多交流。為了方便討論,本人新建了一個微信群(iOS技術討論群),想要加入的,請新增本人微信:zhujinhui207407,【加我前請備註:ios 】,本人部落格http://www.kyson.cn 也在不停的更新中,歡迎

iOS開發快取(記憶體快取

點選有驚喜 前面一片文章介紹瞭如何上傳和下載檔案,這篇文章將介紹一下如何在iOS裝置中進行快取。 這篇文章將只介紹一下將內容快取到記憶體中,下一篇文章就介紹一下在iOS磁碟上快取內容。 使用快取的目的是為了使用的應用程式能更快速的響應使用者輸入,是程式高效的執行

iOS開發opencv學習筆記下載和安裝

1. opencv是什麼? opencv是一個基於BSD開源協議的影象處理開源庫,截止本人編輯時間:2017年6月1日,最新版本為3.2.0。 2.哪裡可以得到opencv的原始碼以及不同平臺的動態庫? opencv的官方地址為http://opencv.org/,可以在這

Qt開發中國象棋篇(工程概述

          最近看一篇關於C++實現中國象棋的部落格,於是基於該博主的框架,自己嘗試實現了一個簡單基於Qt的中國象棋遊戲,只是實現了簡單的人人對戰,還沒有實現較為複雜的人機對戰。主要涉及Qt的重繪事件QPaintEvent,用來實現棋盤的

iOS開發Weex爬坑路環境部署和Devtools Debug(

前言 不多說,直接開始Weex,算是記錄這段時間對新技術的學習積累。期間看了很多Vue.js和Node.js的基礎,順便捋了以下CSS的flex-box佈局等等前端的知識,太多了太雜了,還是用筆記記錄下。直接從官方介紹,開始 補充一個傳送門:和文章沒什麼關係 JS中的async和await

iOS開發再探多執行緒程式設計Grand Central Dispatch詳解

Swift3.0相關程式碼已在github上更新。之前關於iOS開發多執行緒的內容釋出過一篇部落格,其中介紹了NSThread、操作佇列以及GCD,介紹的不夠深入。今天就以GCD為主題來全面的總結一下GCD的使用方式。GCD的歷史以及好處在此就不做過多的贅述了。本篇部落格會通過一系列的例項來好好的總結一下GC

iOS開發opencv學習筆記四使用feature2d識別圖片

使用過vuforia或者亮風臺的朋友應該知道,這兩個平臺對圖片的跟蹤的準備工作是很簡單的,只需要幾張樣本圖片就可以做了。 但是按照上篇的介紹,如果用CascadeClassifier進行物體跟蹤就需要非常非常多的樣本,那麼,要對圖片進行識別跟蹤就沒有像上面說的兩個平臺那樣

iOS開發高階檢視—— UITableView()簡單例子

    表檢視繼承自UIScrollView,這樣的繼承關係使得表檢視可以實現上、下滾動。      UITableView需要實現的兩個協議如下:        UITableViewDatasource:例項化表檢視時,必須採用該方法來實現資料來源的配置        

IOS開發非同步載入網路圖片並快取本地實現瀑布流(

</pre><pre name="code" class="objc"></pre><pre name="code" class="objc">在前面的一篇部落格中,我寫了一個瀑布流照片牆的程式,由於之前的程式載入的圖片是本

Hybrid APP 混合開發模式的選擇路(原生和H5的互動原理)

原文出處:http://www.cnblogs.com/dailc/p/5931322.html 在Hybrid APP中,原生與H5的互動方式在Android和iOS上的實現是有異同的,原因是Android、iOS的通訊機制有所區別,下面介紹原生和H5相互呼叫的方法

IOS開發新增第三方lib或從其他工程引入lib時的連結錯誤ld: symbol(s) not found for architecture i386

首先要確保正確的新增步驟 1)拷貝到新project目錄下 2)新增到工程裡 3)在新工程的targets->Build Phases->target dependencies 點選+ 新增lib 3) 在新工程的targets->Summary->

iOS開發網路程式設計篇三同步,非同步請求差異及用法

在網路請求方式上,有同步和非同步之分,相關內容涉及到執行緒部分知識,這一節咱們需要知道如何去傳送一個同步或者非同步的請求,以及它們二者的區別。 一、同步請求 在網路程式設計第二篇,咱們寫的get,post請求使用的都是同步請求,那結合同步非同步、get/post組

IOS開發HomeKit(

       IOS10中已經自帶了homekit程式。現在由於支援該框架的硬體裝置有限,所以homekit應用還是比較少的,但是由於工作需要,我還是瞭解和學習了一些這方面的知識在這裡還是將這些東西記錄下來,方便以後翻閱,也為剛開始瞭解這方面的小夥伴們提供一些參考。硬體

iOS開發關於Runtime執行時類與物件

Objective-C語言是一門動態語言,它將很多靜態語言在編譯和連結時期做的事放到了執行時來處理。這種動態語言的優勢在於:我們寫程式碼時更具靈活性,如我們可以把訊息轉發給我們想要的物件,或者隨意交換一個方法的實現等。 這種特性意味著Objective-C不僅需要一個編譯器,還需要一個執行時系統