相信大家有很多人在做項目的時候都在使用MJRefresh 控件來實現下拉刷新的功能;
MJRefresh經過不斷的重構與更新迭代,現在不管是功能上還是代碼結構上都是相當不錯的,都是很值我們去學習的.
下面就是MJRefresh開源框架中中主要的一些類文件
MJRefresh主要的類文件
MJRefresh 的使用相信都難不倒大家
今天我主要想和大家分享一下MJRefresh的想法,因為我覺得這才是最重要的,獻丑了,有理解的不對和不深入的地方,請大家多多點評哈!
試想,如果沒有MJRefresh開源框架,公司讓你來寫這樣一個框架?
你應該怎麼寫?
應該從哪幾個方面考慮?
應該怎麼下手?
應該注意一些什麼?
下面我分了六個步驟給大家說一下
第 1 步: 主要說了一下大體思路和注意事項
第 2 步:為什麼使用UIScrollView ?
第 3 步:如何給UIScrollView增加新的屬性header ?
第 4 步:Header類裡主要寫一些什麼 ?
第 5 步:如何利用KVO的方式來監聽偏移量的變化(設置刷新狀態)?
第 6 步:實例化Header類的對象 去給 UIScrollView的屬性header賦值 ?
step1:
如果想給UITableView 和UICollectionView 增加下拉刷新 上提加載的功能
其實不要想的太復雜,其實就是給他們:
1.先增加一個頭視圖(header) 和 尾視圖(footer)
2.然後就是考慮狀態的變化(正在刷新啊,刷新完成啊),通過偏移量來判斷
3.最後給這些狀態設置一些監聽事件(下拉刷新的時候調用什麼方法,沒有數據了調用什麼方法等)
如果能實現上面幾點的話,一個簡單粗糙的下拉刷新的控件就可以實現了
但是具體操作的時候我們還是要考慮幾點問題:
1.首先要滿足以後能夠很方便給TableView和CollectionView的去增加這個特性,
2.能夠很好的去適配最新的SDK
3.增加特性後要減少甚至避免此特性(下拉刷新)不與其它UI控件和其他特性發生沖突
根據上面的幾點問題我們有以下兩種選擇:
1.自己重寫一套UIScrollView並且加上下拉刷新的特性(但是很有難度,不建議這樣);
2.最好的方式是使用IOS的特性Category來增加下拉刷新的功能(選擇這種方式來實現);
step2:
接下來我們要考慮的就是給TableView加還是給UICollectionView?(其實很簡單,大神們可以忽略這個問題)我們選擇的是UIScrollView
為什麼使用ScrollView?而不使用TableView 和 CollectionView增加Category ?
大家應該都知道 UITableView 和 UICollectionView 都是繼承於 ScrollView
如果我們使用UIScrollView的話,以後不管是tableView 和 CollectionView都可以直接使用下拉刷新的特性
但我們如果使用UITableView的話,我們肯定還必須為UICollectionView 寫一套新的下拉刷新的方法;使用UIScrollView 會很大程度上提高我們這個下拉組件的延展性和兼容性
step3:
接下來就是需要來考慮我們如何使用UIScrollView和Catgory的特性來增加下拉刷新和上提加載的功能 ? ? ?
滿足下面兩點:
1.下拉刷新?上提加載?
2.為了方便以後容易使用?
最好的方式是 給UIScrollView 添加兩個屬性 一個是header 一個是Footer ,這樣以後就可以直接利用這兩個屬性做事情了;
這個時候我們就需要考慮給UIScrollView添加屬性了,如何給UIScrollView添加屬性?
有點IOS基礎的應該都知道,我們不能直接給Category添加屬性;
但是可用通過采用動態添加屬性的方法objc_setAssociatedObject()和objc_getAssociatedObject()函數給UIScrollView動態添加屬性
這是一種關聯對象的技巧(AssociatedObject)
給UIScrollView增加header屬性
當然添加Footer的方法也是這樣,添加Footer的時候只需要修改一下Key 就好,就先不講Footer的實現了
step4:
既然添加完屬性,那此時我們就需要想著如何給屬性賦值?
所以接下來我們的工作就是寫一個header的類
然後用Header類的對象給我們新增加的scrollView的header屬性賦值
#當然現在MJRefresh這個框架已經進行了代碼重構,現在框架的結構比較清晰,但是對一些剛開始接觸IOS的同學看起來就會有些費勁了_#現在咱們只講一些主要的代碼,先不考慮MJRefresh的代碼結構#因為它現在的代碼是重構之後的,而咱們現在講的是實現的思路#先按照我們正常的思路來分析一下
首先創建一個類Header去繼承UIView 但header類裡面要寫什麼呢?
1.首先肯定少不了一些主要的布局 如 下拉的ImageView,以及UIActivityIndicatorView等
2.其次是 下拉刷新那一塊會有很多的狀態的變化,比如 正在刷新中,刷新完成,剛開始刷新等狀態的判斷,(這些狀態我們需要通過 UIScrollView 的偏移量來計算這些狀態。這一塊主要就是一些邏輯判斷,如何計算這次暫時不講了)
3.最後就是看需求了,如果需要時間的加時間,需要GIF的加GIF動畫;
普通的Header
帶GIF的header
step5:
如何計算刷新狀態呢 ?
所以此時我們不得不需要另一個知識點:事件監聽(監聽 UIScrollView的偏移量變化情況);
說到監聽的話,IOS有幾種經典的方式用來監聽(以後有時間會給大家講一下它們的優缺點和用法):
1.KVO
2.NSNotificationCenter
3.Delegate等
MJRefresh中使用的是KVO的方式監聽偏移量:
下面的willMoveToSuperView 方法中傳過來的newSuperView 是你實現此功能的UITableView 和 UICollectionView的對象,此方法只在設置tableView的下拉和上提的時候執行一次(或者說只在當前頁面初始化的時候執行一次);
此時我們通過 addObserver forKeyPath 的方式監聽了ContentOffset的變化
設置偏移量監聽
由於我們在上面設置了偏移量的監聽,那麼當UIScrollView的偏移量變化時,都會執行 observerValueForKeyPath方法
在這裡面我們可以做一系列的邏輯判斷,比如 刷新狀態的變化,一些動畫效果什麼的(具體的判斷就不說了,不然就就偏離了這篇文章的主題)
監聽事件的執行
具體的偏移量變化判斷暫不講解;
偏移量邏輯判斷方法
step6:
至此,我們基本上就把MJRefresh的下拉刷新的實現的大體流程給過了一遍,以後如果想豐富一下MJRefresh的話,比如增加時間的變化,或者增加GIF圖片的效果,我覺得都不是太難的問題了,因為框架已經搭起來了以後想往裡面塞什麼東西,那就看需求了
最後我們要做的就是 寫一個方法去實例化一個header的對象,然後將這個對象賦值給我們的UIScrollView的header屬性
實例化一個header的對象
這樣就可以實現一個簡單的下拉刷新控件
這邊文章主要講了一下我們寫MJRefresh的思路,沒有講一些具體實現方法
個人認為 編程重要的是思路,是想法,把想法理解透了,以後不管是OC 還是Android 還是Java PHP都是可以用的上的
以上只是個人對MJRefresh的理解,有一些理解不到的地方希望大家多多指教,多多批評
demo下載地址:http://www.code4app.com/thread-10770-1-1.html
文章轉自 劉敬的簡書