1. 程式人生 > >iOS開發之資訊類App常用分類控制元件的封裝與實現(CollectionView+Swift3.0+)

iOS開發之資訊類App常用分類控制元件的封裝與實現(CollectionView+Swift3.0+)

今天部落格中,我們就來實現一下一些常用資訊類App中常用的分類選擇的控制元件的封裝。本篇部落格中沒有使用到什麼新的技術點,如果非得說用到了什麼新的技術點的話,那麼勉強的說,用到了一些iOS9以後UICollectionView新增的一些新的特性。本篇部落格所涉及的技術點主要有UICollectionView的Cell移動手勢識別控制元件封裝閉包回撥,面向介面程式設計,Swift中的泛型等等。這些技術點在之前的部落格中也多次使用到,只不過本篇部落格使用這些技術點來完成我們的具體需求。

一、例項執行效果

先入為主,下方這個效果,就是本篇部落格所涉及Demo的執行效果。當然下方的效果是一些資訊類App中選擇分類時,常用的部分。主要還是對UICollectionView

的使用。當然,下方效果的實現,網上也不乏相應的例項。雖然本篇部落格的效果與其他類似的效果類似,但是程式碼設計以及結構實現時還是有所區別的。下方效果的實現使用了iOS9以後的UICollectionView才支援的更新Cell的方法,稍後會詳細介紹到。當然,本篇部落格我們依然使用Swift3.0來實現的。

在之前的部落格中,我們系列的介紹了UICollectionView的各種回撥,以及如何自定義CollectionView的佈局,並給出瞭如何使用CollectionView自定義瀑布流。關於之前的部落格請移步於《》。

  

我們可以使用Reveal來檢視上述效果的層級關係。下方就是我們使用Reveal來檢視的效果。從下方的效果中我們不難看出,該頁面的實現並不複雜。主要還是對UICollectionView的使用。

  

上面這個效果就是我們今天部落格中所實現的效果,而下方這兩個效果是我們之前在聊UICollectionView以及自定義佈局時所給出的相應的Demo, 下方的Demo所對應的原始碼也在Gitbub上進行了分享。還是那句話,今天部落格的內容依然是對UICollectionView的應用。

UICollectionView這個控制元件是非常強大的,之所以強大,源於其可定製性比較高,靈活多變。

      

二、控制元件的呼叫

我們將上述分類選擇的控制元件進行了封裝,接下來,我們將會給出其初始化和呼叫的方式。下方就是我們所封裝控制元件的呼叫方式,下方的二維陣列dataSource就是我們所封裝控制元件中的CollectionView中的資料來源,該資料來源中的資料項要遵循我們指定的CEThemeDataSourceProtocal

協議。稍後我們會給出該協議中所以對應的內容。

DataSourceTools類中的createDataSource()類方法就負責建立我們需要的測試資料。資料來源建立好後,在例項化CESelectThemeController物件時,將相應的資料來源傳給我們的控制元件即可。然後給控制元件的物件設定更新資料來源的閉包回撥,也就是說,當我們使用該封裝的控制元件對DataSource操作完畢後,會執行下方的閉包回撥,將更新後的資料來源傳給呼叫者。如下所示:

  

CEThemeDataSourceProtocal協議就規範了資料來源中的資料項必須要實現的方法,下方就是CEThemeDataSourceProtocal協議的實現程式碼。當然該協議的程式碼實現比較簡單,就一個menuItemName()方法,該方法的返回值是一個字串。該字串就是我們要在Cell上顯示的Menu的名字。

  

下方就是建立我們的資料項的測試資料相關程式碼。下方的MeteData類就是我們要在上述控制元件測Cell中顯示的資料。該類實現了CEThemeDataSourceProtocal協議,並給出了menuItemName()的方法實現。

DataSourceTools中的createDataSource()方法中負責建立我們的測試資料,通過迴圈例項化MeteData並存入二維陣列中,並將該二維資料組進行返回。該方法返回的二維陣列就是我們需要的資料來源。

  

三、控制元件核心程式碼介紹

上面我們簡單介紹了該控制元件的呼叫方式,接下來我們來看一下該控制元件的核心程式碼的實現。說吧了,就是長按手勢識別以及CollectionView的Cell的移動。下方我們將詳細的介紹一下該控制元件的核心程式碼的實現。

1. UICollectionViewDataSource

下方就是該控制元件中使用UICollectionViewDataSource的代理方法。前面幾個我們之前介紹過的代理方法就不做過多贅述了,下方兩個畫框的就是本篇部落格的主角,一個是開啟Cell移動的代理方法,另一個是移動後更新資料來源的方法,具體如下所示。

  

2、為CollectionView新增長按手勢

接下來要做的就是給CollectionView新增LongPressGestureRecognizeaddGestureRecognizer()方法負責為我們的CollectionView新增長按手勢,longPress()方法就是該長按手勢所觸發的方法。手勢開始時,我們呼叫longPressBegin()方法。手勢改變時,我們呼叫longPressChange()方法。手勢結束時,我們呼叫longPressEnd()。這三個方法是本篇部落格的關鍵,下方會具體給出其實現方式。

  

3、longPressBegin()方法的實現

下方是長按手勢開始時所觸發的方法,首先根據觸控的點來獲取該點所在cell的IndexPath。如果該Cell不是第一個Section中的Cell, 那麼就不觸發手勢開始的事件,因為我們規定只有第一個Section中的Cell才有長按拖動手勢。

如果Cell符合我們的要求,我們就呼叫UICollectionView的beginInteractiveMovementForItem()方法來啟動移動Item功能。當然,該方法是iOS9以後才新增的。啟動後我們將當前的Cell隱藏,然後將當前的Cell生成快照,讓後讓該快照跟著我們的手指移動即可。具體程式碼如下所示:

  

4、longPressChange()方法的實現

下方方法就是手指移動時所觸發的方法,該方法的程式碼比較簡單,主要是改變我們快照的座標,讓Cell的快照隨著手指的移動而移動。然後再呼叫updateInteractiveMovementTargetPosition()。呼叫該方法時,會執行DataSource代理中更新資料來源的代理方法,也就是上面DataSource代理方法中最後一個更新資料來源的方法。

  

5、longPressEnd()方法實現

該方法的主要功能是在手勢結束後做一些善後工作,如結束移動,然後移除掉Cell的快照並顯示隱藏掉的cell。具體如下所示:

  

今天的部落格就先介紹到這兒吧,上面只是本篇部落格所涉及Demo的一小部分程式碼,完整的程式碼請移步於下方的github分享連結。