你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 如何寫一套下拉刷新的控件:MJRefresh原理淺析

如何寫一套下拉刷新的控件:MJRefresh原理淺析

編輯:IOS開發基礎
相信大家有很多人在做項目的時候都在使用MJRefresh 控件來實現下拉刷新的功能;
MJRefresh經過不斷的重構與更新迭代,現在不管是功能上還是代碼結構上都是相當不錯的,都是很值我們去學習的.

下面就是MJRefresh開源框架中中主要的一些類文件

1.png

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)

2.png給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動畫;

3.png

普通的Header

4.png

帶GIF的header

step5:

如何計算刷新狀態呢 ?
所以此時我們不得不需要另一個知識點:事件監聽(監聽 UIScrollView的偏移量變化情況);
說到監聽的話,IOS有幾種經典的方式用來監聽(以後有時間會給大家講一下它們的優缺點和用法):
  • 1.KVO
  • 2.NSNotificationCenter
  • 3.Delegate等
MJRefresh中使用的是KVO的方式監聽偏移量:

下面的willMoveToSuperView 方法中傳過來的newSuperView 是你實現此功能的UITableView 和 UICollectionView的對象,此方法只在設置tableView的下拉和上提的時候執行一次(或者說只在當前頁面初始化的時候執行一次);
此時我們通過 addObserver forKeyPath 的方式監聽了ContentOffset的變化

5.png

設置偏移量監聽
由於我們在上面設置了偏移量的監聽,那麼當UIScrollView的偏移量變化時,都會執行 observerValueForKeyPath方法
在這裡面我們可以做一系列的邏輯判斷,比如 刷新狀態的變化,一些動畫效果什麼的(具體的判斷就不說了,不然就就偏離了這篇文章的主題)

6.png

監聽事件的執行
具體的偏移量變化判斷暫不講解;

7.png

偏移量邏輯判斷方法

step6:

至此,我們基本上就把MJRefresh的下拉刷新的實現的大體流程給過了一遍,以後如果想豐富一下MJRefresh的話,比如增加時間的變化,或者增加GIF圖片的效果,我覺得都不是太難的問題了,因為框架已經搭起來了以後想往裡面塞什麼東西,那就看需求了


最後我們要做的就是 寫一個方法去實例化一個header的對象,然後將這個對象賦值給我們的UIScrollView的header屬性

8.png

實例化一個header的對象
這樣就可以實現一個簡單的下拉刷新控件

9.png

這邊文章主要講了一下我們寫MJRefresh的思路,沒有講一些具體實現方法

個人認為 編程重要的是思路,是想法,把想法理解透了,以後不管是OC 還是Android 還是Java PHP都是可以用的上的

以上只是個人對MJRefresh的理解,有一些理解不到的地方希望大家多多指教,多多批評


demo下載地址:http://www.code4app.com/thread-10770-1-1.html



文章轉自 劉敬的簡書
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved