阅读MJRefresh源码

先看一下源码目录结构:

目录结构

1.Base

Base

MJRefreshComponent:基类(继承至UIView)

```

/** 刷新控件的状态 */

typedefNS_ENUM(NSInteger, MJRefreshState) {

    /** 普通闲置状态 */

    MJRefreshStateIdle =1,

    /** 松开就可以进行刷新的状态 */

    MJRefreshStatePulling,

    /** 正在刷新中的状态 */

    MJRefreshStateRefreshing,

    /** 即将刷新的状态 */

    MJRefreshStateWillRefresh,

    /** 所有数据加载完毕,没有更多的数据了 */

    MJRefreshStateNoMoreData

};

```

定义的三种状态的回调block

```

/** 进入刷新状态的回调 */

typedef void (^MJRefreshComponentRefreshingBlock)(void);

/** 开始刷新后的回调(进入刷新状态后的回调) */

typedef void (^MJRefreshComponentbeginRefreshingCompletionBlock)(void);

/** 结束刷新后的回调 */

typedef void (^MJRefreshComponentEndRefreshingCompletionBlock)(void);

#pragma mark - 交给子类们去实现()

/** 初始化 */

- (void)prepare NS_REQUIRES_SUPER;//这里可以自定义控件或者设置GIF图片(初始化的时候调用)

/** 摆放子控件frame */

- (void)placeSubviews NS_REQUIRES_SUPER;//这里做布局(layoutSubviews时调用)

/** 当scrollView的contentOffset发生改变的时候调用 */

- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change NS_REQUIRES_SUPER;

/** 当scrollView的contentSize发生改变的时候调用 */

- (void)scrollViewContentSizeDidChange:(NSDictionary *)change NS_REQUIRES_SUPER;

/** 当scrollView的拖拽状态发生改变的时候调用 */

- (void)scrollViewPanStateDidChange:(NSDictionary *)change NS_REQUIRES_SUPER;

```

Header

  MJRefreshHeader,MJRefreshStateHeader,MJRefreshNormalHeader,MJRefreshGifHeader

Footer(分为back和auto:是否自动刷新,尾部跟随)

UIScrollView分类:给UIScrollView添加一个控件(header,footer)

```

- (void)setMj_header:(MJRefreshHeader *)mj_header

{

    if (mj_header != self.mj_header) {

        // 删除旧的,添加新的

        [self.mj_header removeFromSuperview];

        [self insertSubview:mj_header atIndex:0];

        // 存储新的

        objc_setAssociatedObject(self, &MJRefreshHeaderKey,

                                mj_header, OBJC_ASSOCIATION_RETAIN);//runtime给对象绑定属性

    }

}

- (MJRefreshHeader *)mj_header

{

    return objc_getAssociatedObject(self, &MJRefreshHeaderKey);//runtime获取属性

}

```

footer也是类似

原理:

1.通过UIScrollView分类:给UIScrollView添加一个控件(header,footer)

2.header和footer定义回调block,获取到父控件UIScrollView

3.header和footer通过KVO,观察父控件UIScrollView的offset,contentSize

[self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentOffset options:options context:nil];

    [self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentSize options:options context:nil];

4.根据偏移量去做相关的操作(UI显示和触发回调block)

5.完成观察,刷新完成

自定义:可以在初始化重写prepare方法,自定义样式

你可能感兴趣的:(阅读MJRefresh源码)