123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- // 代码地址: https://github.com/CoderMJLee/MJRefresh
- // 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
- // MJRefreshComponent.m
- // MJRefreshExample
- //
- // Created by MJ Lee on 15/3/4.
- // Copyright (c) 2015年 小码哥. All rights reserved.
- //
- #import "MJRefreshComponent.h"
- #import "MJRefreshConst.h"
- #import "UIView+MJExtension.h"
- #import "UIScrollView+MJRefresh.h"
- @interface MJRefreshComponent()
- @property (strong, nonatomic) UIPanGestureRecognizer *pan;
- @end
- @implementation MJRefreshComponent
- #pragma mark - 初始化
- - (instancetype)initWithFrame:(CGRect)frame
- {
- if (self = [super initWithFrame:frame]) {
- // 准备工作
- [self prepare];
-
- // 默认是普通状态
- self.state = MJRefreshStateIdle;
- }
- return self;
- }
- - (void)prepare
- {
- // 基本属性
- self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
- self.backgroundColor = [UIColor clearColor];
- }
- - (void)layoutSubviews
- {
- [super layoutSubviews];
-
- [self placeSubviews];
- }
- - (void)placeSubviews{}
- - (void)willMoveToSuperview:(UIView *)newSuperview
- {
- [super willMoveToSuperview:newSuperview];
-
- // 如果不是UIScrollView,不做任何事情
- if (newSuperview && ![newSuperview isKindOfClass:[UIScrollView class]]) return;
-
- // 旧的父控件移除监听
- [self removeObservers];
-
- if (newSuperview) { // 新的父控件
- // 设置宽度
- self.mj_w = newSuperview.mj_w;
- // 设置位置
- self.mj_x = 0;
-
- // 记录UIScrollView
- _scrollView = (UIScrollView *)newSuperview;
- // 设置永远支持垂直弹簧效果
- _scrollView.alwaysBounceVertical = YES;
- // 记录UIScrollView最开始的contentInset
- _scrollViewOriginalInset = _scrollView.contentInset;
-
- // 添加监听
- [self addObservers];
- }
- }
- - (void)drawRect:(CGRect)rect
- {
- [super drawRect:rect];
-
- if (self.state == MJRefreshStateWillRefresh) {
- // 预防view还没显示出来就调用了beginRefreshing
- self.state = MJRefreshStateRefreshing;
- }
- }
- #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;
- }
- - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
- {
- // 遇到这些情况就直接返回
- if (!self.userInteractionEnabled) return;
-
- // 这个就算看不见也需要处理
- if ([keyPath isEqualToString:MJRefreshKeyPathContentSize]) {
- [self scrollViewContentSizeDidChange:change];
- }
-
- // 看不见
- if (self.hidden) return;
- if ([keyPath isEqualToString:MJRefreshKeyPathContentOffset]) {
- [self scrollViewContentOffsetDidChange:change];
- } else if ([keyPath isEqualToString:MJRefreshKeyPathPanState]) {
- [self scrollViewPanStateDidChange:change];
- }
- }
- - (void)scrollViewContentOffsetDidChange:(NSDictionary *)change{}
- - (void)scrollViewContentSizeDidChange:(NSDictionary *)change{}
- - (void)scrollViewPanStateDidChange:(NSDictionary *)change{}
- #pragma mark - 公共方法
- #pragma mark 设置回调对象和回调方法
- - (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action
- {
- self.refreshingTarget = target;
- self.refreshingAction = action;
- }
- #pragma mark 进入刷新状态
- - (void)beginRefreshing
- {
- [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{
- self.alpha = 1.0;
- }];
- self.pullingPercent = 1.0;
- // 只要正在刷新,就完全显示
- if (self.window) {
- self.state = MJRefreshStateRefreshing;
- } else {
- self.state = MJRefreshStateWillRefresh;
- // 刷新(预防从另一个控制器回到这个控制器的情况,回来要重新刷新一下)
- [self setNeedsDisplay];
- }
- }
- #pragma mark 结束刷新状态
- - (void)endRefreshing
- {
- self.state = MJRefreshStateIdle;
- }
- #pragma mark 是否正在刷新
- - (BOOL)isRefreshing
- {
- return self.state == MJRefreshStateRefreshing || self.state == MJRefreshStateWillRefresh;
- }
- #pragma mark 自动切换透明度
- - (void)setAutoChangeAlpha:(BOOL)autoChangeAlpha
- {
- self.automaticallyChangeAlpha = autoChangeAlpha;
- }
- - (BOOL)isAutoChangeAlpha
- {
- return self.isAutomaticallyChangeAlpha;
- }
- - (void)setAutomaticallyChangeAlpha:(BOOL)automaticallyChangeAlpha
- {
- _automaticallyChangeAlpha = automaticallyChangeAlpha;
-
- if (self.isRefreshing) return;
-
- if (automaticallyChangeAlpha) {
- self.alpha = self.pullingPercent;
- } else {
- self.alpha = 1.0;
- }
- }
- #pragma mark 根据拖拽进度设置透明度
- - (void)setPullingPercent:(CGFloat)pullingPercent
- {
- _pullingPercent = pullingPercent;
-
- if (self.isRefreshing) return;
-
- if (self.isAutomaticallyChangeAlpha) {
- self.alpha = pullingPercent;
- }
- }
- #pragma mark - 内部方法
- - (void)executeRefreshingCallback
- {
- dispatch_async(dispatch_get_main_queue(), ^{
- if (self.refreshingBlock) {
- self.refreshingBlock();
- }
- if ([self.refreshingTarget respondsToSelector:self.refreshingAction]) {
- MJRefreshMsgSend(MJRefreshMsgTarget(self.refreshingTarget), self.refreshingAction, self);
- }
- });
- }
- @end
- @implementation UILabel(MJRefresh)
- + (instancetype)label
- {
- UILabel *label = [[self alloc] init];
- label.font = MJRefreshLabelFont;
- label.textColor = MJRefreshLabelTextColor;
- label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
- label.textAlignment = NSTextAlignmentCenter;
- label.backgroundColor = [UIColor clearColor];
- return label;
- }
- @end
|