当前位置: 首页 > 工具软件 > MJRefresh > 使用案例 >

MJRefresh实现原理(详细版)

壤驷德寿
2023-12-01

MJRefresh实现原理

 

大家常用的UITableView  UIClollectionView上拉 下拉加载数据很常见。

以下分析MJRefresh实现方法

首先看下,框架是如何使用的,只需如下2行代码即可实现下拉加载数据

self.collectionView.header = [MJRefreshNormalHeaderheaderWithRefreshingTarget:selfrefreshingAction:@selector(loadNewData)];

[self.collectionView.headerbeginRefreshing];

对此肯定很多同学不理解,2行代码是怎么实现的呢,它是怎么控collectionView下拉,松手后调用loadNewData这个方法呢?

 

首先请看UITableView  UIClollectionView是继承自UIScrollView的,他们是没有header这个属性的。(header是自定义的一个UIView)

要想给即有的类动态增加一个属性当然要写个分类用到运行时了,请看如下代码:

.h文件

@class MJRefreshHeader;

@interface UIScrollView (MJRefresh)

@property (strong,nonatomic) MJRefreshHeader *header;

@end

.m实现文件

@implementation UIScrollView (MJRefresh)

static constchar MJRefreshHeaderKey = '\0';

- (void)setHeader:(MJRefreshHeader *)header

{

    if (header !=self.header) {

        // 删除旧的,添加新的

        [self.headerremoveFromSuperview];

        [selfaddSubview:header];

        objc_setAssociatedObject(self, &MJRefreshHeaderKey,

                                 header, OBJC_ASSOCIATION_ASSIGN);

    }

}

- (MJRefreshHeader *)header

{

    returnobjc_getAssociatedObject(self, &MJRefreshHeaderKey);

}

以上代码的作用是给继承自 UIScrollView的类动态增加了一个自定义的header属性

 [self addSubview:header];这个self其实就是调用者本身即self.collectionView现在就有了一个自定义的header被加在了self.collectionView上了

但又是如何控制collectionView下拉后,header显示并调用加载数据方法呢?至少得要知道,下拉时ContentOffset.Y的偏移量吧,但是怎么拿到呢。

答案是在header被添加到self.collectionView时,在header这个类中重写了

- (void)willMoveToSuperview:(UIView *)newSuperview//在一个子视图将要被添加到另一个视图的时候发送此消息

这个newSuperview就是self.collectionView,这时只需中header中申明一个成员变理__weakUIScrollView *_scrollView;/** 父控件 */

_scrollView=newSuperview

利用KVO去监听ContentOffset这个值的改变,

[self.scrollViewaddObserver:selfforKeyPath:@"contentOffset"options:optionscontext:nil];

下面就是监听contentOffset值的变化,做相应处理,最后调用objc_msgSend(self.refreshingTarget, self.refreshingAction,self);刷新

原理大概就是这样,当然实际写的时候里面细节有很多,还是很佩服MJ老师的^_^。







 类似资料: