MJRefresh源码阅读(一)

2020-07-01  本文已影响0人  落叶兮兮

看源代码时首先应该找到代码在github上的地址,基本上作者都会在github上的README上介绍使用的用法。
源码的地址为https://github.com/CoderMJLee/MJRefresh
,在readME中作者有列出整个代码的结构,如下图所示:

image.png
从上面的结构,我们可以看出,从刷新控件的基类MJRefreshComponent开始看起
1.看代码发现在交给子类方法去实现的方法后面都有添加一个宏NS_REQUIRES_SUPER,该宏的定义为:

define NS_REQUIRES_SUPER attribute((objc_requires_super))

_attribute((objc_requires_super))在2012年9月首次引入到CLANG中,并在2013年10月进行了介绍。在OS X和iOS上,现在都有一个NS_REQUIRES_SUPER宏,它根据编译器支持有条件地包装objc_requires_super属性。一旦方法声明附加了这个宏,编译器将会产生一个警告,如果super没有被覆盖该方法的子类调用。
这个宏可以有效的提醒我们忘记在子类中写

【super 父类方法】;

会弹出一个警告提醒我们。
2.在initWithFrame中调用了prepare方法

- (void)prepare
{
    // 基本属性
    self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    self.backgroundColor = [UIColor clearColor];
}

这是为了适配不同大小的视图,使该刷新UIView和父视图左右的间距保持不变,相应的UIViewAutoresizing枚举类的各个含义如下:

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    //不会随父视图的改变而改变
    UIViewAutoresizingNone                 = 0,
    //自动调整view与父视图左边距,以保证右边距不变
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    //自动调整view的宽度,保证左边距和右边距不变
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    //自动调整view与父视图右边距,以保证左边距不变
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    //自动调整view与父视图上边距,以保证下边距不变
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
   //自动调整view的高度,以保证上边距和下边距不变
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
   //自动调整view与父视图的下边距,以保证上边距不变
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};

之后,在layoutSubViews中调用方法

//默认布局,可以在子类中进行更改
[self placeSubViews];

之后重写了- (void)willMoveToSuperview:(UIView *)newSuperview方法,本身这个方法是不执行任何操作的,但是我们可以重写它添加一些我们想要的额外操作,该方法是父视图发生变化时调用。
在方法里面移除旧的UIScrollView的监听,给newSuperview添加新的监听
添加新的监听的方法为:

#pragma mark - KVO监听
//添加监听
- (void)addObservers
{
    NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
    [self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentOffset options:options context:nil];
    [self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentSize options:options context:nil];
//添加拖拽手势
    self.pan = self.scrollView.panGestureRecognizer;
    [self.pan addObserver:self forKeyPath:MJRefreshKeyPathPanState options:options context:nil];
}

//移除监听
- (void)removeObservers
{
    [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentOffset];
    [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentSize];
//移除拖拽手势
    [self.pan removeObserver:self forKeyPath:MJRefreshKeyPathPanState];
    self.pan = nil;
}

关于kvo的解释,可以参考这个作者的链接
https://www.jianshu.com/p/3bdc82e0ed4e

上一篇 下一篇

猜你喜欢

热点阅读