MJRefresh GitHub地址:https://github.com/CoderMJLee/MJRefresh
利用業餘時間研究了一下iOS的開發,發現OC特定的語法方式吸引了我,而且iOS開發中有很多有趣的東西,正是如此,重新激起了我對開發學習的興趣。自學過程中,知道了這個MJRefresh,MJ真乃大神也。
廢話不多說,MJRefresh整合了UIView,UICollectionView,UITableView的上下拉重新整理功能,而且還有自定義文字,動畫等功能。針對GitHub上的原始碼研究了一翻,打算照抄一遍,理解裡面的機制並且期待能從自己的實戰中學到新的東西。相信敲完一遍之後對它的理解又是一個新的層次。
MJRefresh的結構大致是這樣子的:
MJRefreshComponent自然是父類,它定義了基本的文字大小,顏色,重新整理事件,block,以及開始重新整理,結束重新整理等基本操作和屬性。
1 @interface MJRefreshComponent : UIView 2 { 3 UIEdgeInsets _scrollViewOriginalInset; 4 __weak UIScrollView *_scrollView; 5 } 6 7 #pragma mark - 文書處理 8 /** 文字顏色 */ 9 @property (strong, nonatomic) UIColor *textColor; 10 /** 字型大小 */ 11 @property (strong, nonatomic) UIFont *font; 12 13 #pragma mark - 重新整理處理 14 /** 正在重新整理的回撥 */ 15 @property (copy, nonatomic) void (^refreshingBlock)(); 16 /** 設定回撥物件和回撥方法 */ 17 - (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action; 18 @property (weak, nonatomic) id refreshingTarget; 19 @property (assign, nonatomic) SEL refreshingAction; 20 /** 進入重新整理狀態 */ 21 - (void)beginRefreshing; 22 /** 結束重新整理狀態 */ 23 - (void)endRefreshing; 24 /** 是否正在重新整理 */ 25 - (BOOL)isRefreshing; 26 @end
我個人認為,最重要的兩個類就是 MJRefreshHeader和MJRefreshFooter。因為重新整理事件的精髓就在這兩個類裡面,Footer不多做介紹。我個人理解是,主要通過KVO監聽 contentOffSet屬性變化來判斷當時是否是重新整理、還是下拉、還是正在重新整理或者改變重新整理狀態,核心程式碼當然我還是因為自身水平的原因沒太看懂,相信敲完一遍之後會明白吧。核心程式碼如下:
#pragma mark 根據contentOffset調整state - (void)adjustStateWithContentOffset { if (self.state != MJRefreshHeaderStateRefreshing) { // 在重新整理過程中,跳轉到下一個控制器時,contentInset可能會變 _scrollViewOriginalInset = _scrollView.contentInset; } // 在重新整理的 refreshing 狀態,動態設定 content inset if (self.state == MJRefreshHeaderStateRefreshing ) { if(_scrollView.contentOffset.y >= -_scrollViewOriginalInset.top ) { _scrollView.mj_insetT = _scrollViewOriginalInset.top; } else { _scrollView.mj_insetT = MIN(_scrollViewOriginalInset.top + self.mj_h, _scrollViewOriginalInset.top - _scrollView.contentOffset.y); } return; } // 當前的contentOffset CGFloat offsetY = _scrollView.mj_offsetY; // 頭部控制元件剛好出現的offsetY CGFloat happenOffsetY = - _scrollViewOriginalInset.top; // 如果是向上滾動到看不見頭部控制元件,直接返回 if (offsetY >= happenOffsetY) return; // 普通 和 即將重新整理 的臨界點 CGFloat normal2pullingOffsetY = happenOffsetY - self.mj_h; if (_scrollView.isDragging) { self.pullingPercent = (happenOffsetY - offsetY) / self.mj_h; if (self.state == MJRefreshHeaderStateIdle && offsetY < normal2pullingOffsetY) { // 轉為即將重新整理狀態 self.state = MJRefreshHeaderStatePulling; } else if (self.state == MJRefreshHeaderStatePulling && offsetY >= normal2pullingOffsetY) { // 轉為普通狀態 self.state = MJRefreshHeaderStateIdle; } } else if (self.state == MJRefreshHeaderStatePulling) {// 即將重新整理 && 手鬆開 self.pullingPercent = 1.0; // 開始重新整理 self.state = MJRefreshHeaderStateRefreshing; } else { self.pullingPercent = (happenOffsetY - offsetY) / self.mj_h; } }
最後呢,通過UIScrollView+MJRefresh擴充套件來實現UIScrollView的控制元件下拉重新整理整合。每多讀一次程式碼就有一次新的收穫。還等什麼,趕緊去敲出來吧。