MJRefresh九MJRefreshLefter

MJRefreshLefter


参照MJRefreshHeader改写支持ScrollView横向滚动刷新
MJRefreshLefter.h

#import "MJRefreshComponent.h"

@interface MJRefreshLefter : MJRefreshComponent
/** 创建header */
+ (instancetype)lefterWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock;
/** 创建header */
+ (instancetype)lefterWithRefreshingTarget:(id)target refreshingAction:(SEL)action;

/** 这个key用来存储上一次下拉刷新成功的时间 */
@property (copy, nonatomic) NSString *lastUpdatedTimeKey;
/** 上一次下拉刷新成功的时间 */
@property (strong, nonatomic, readonly) NSDate *lastUpdatedTime;

/** 忽略多少scrollView的contentInset的top */
@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetLeft;
@end

MJRefreshComponent.m

#import "MJRefreshLefter.h"
@interface MJRefreshLefter()
@property (assign, nonatomic) CGFloat insetTDelta;
@property (nonatomic,strong) NSMutableDictionary * stateTextDictM;
@property (nonatomic,strong) UILabel * stateLbl;
@property (nonatomic,strong) UIImageView * arrowImageView;
@property (nonatomic,strong) UIActivityIndicatorView * indicator;
@end

@implementation MJRefreshLefter

+ (instancetype)lefterWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock
{
    MJRefreshLefter *cmp = [[MJRefreshLefter alloc] init];
    cmp.refreshingBlock = refreshingBlock;
    return cmp;
}
+ (instancetype)lefterWithRefreshingTarget:(id)target refreshingAction:(SEL)action
{
    MJRefreshLefter *cmp = [[MJRefreshLefter alloc] init];
    [cmp setRefreshingTarget:target refreshingAction:action];
    return cmp;
}
#pragma mark - 覆盖父类的方法
- (void)prepare
{
    [super prepare];
    // 设置key
    self.lastUpdatedTimeKey = @"MJRefreshLefterLastUpdatedTimeKey";
    
    
}
- (void)placeSubviews
{
    [super placeSubviews];
    
    // 设置y值(当自己的高度发生改变了,肯定要重新调整Y值,所以放到placeSubviews方法中设置y值)
    self.mj_x = - self.mj_w - self.ignoredScrollViewContentInsetLeft;
}
- (void)willMoveToSuperview:(UIView *)newSuperview
{
    [super willMoveToSuperview:newSuperview];
    // 设置高度
    self.mj_w = 54.0f;
    self.mj_x = - self.mj_w - self.ignoredScrollViewContentInsetLeft;
    self.scrollView.alwaysBounceVertical = NO;
    self.scrollView.alwaysBounceHorizontal = YES;
    
    [self addSubview:self.arrowImageView];
    [self addSubview:self.stateLbl];
    [self addSubview:self.indicator];
    
    [self scrollViewPanStateDidChange:nil];
}
- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change
{
    [super scrollViewContentOffsetDidChange:change];
    // 在刷新的refreshing状态
    if (self.state == MJRefreshStateRefreshing) {
        // 没有superView,也就是没加载到其他的View上
        if (self.window == nil) return;
        
        // ??????
        // sectionheader停留解决
//        CGFloat insetL = - self.scrollView.mj_offsetX > _scrollViewOriginalInset.left? _scrollView.mj_offsetX:_scrollViewOriginalInset.left;
//        insetL = insetL > self.mj_w+_scrollViewOriginalInset.left?self.mj_h+_scrollViewOriginalInset.left:insetL;
//        self.scrollView.mj_insetL = insetL;
//        
//        self.insetTDelta = _scrollViewOriginalInset.left-insetL;
        return;
    }
    
    // 跳转到下一个控制器时,contentInset可能会变
    _scrollViewOriginalInset = self.scrollView.contentInset;
    // 当前的contentOffset
    CGFloat offsetX = self.scrollView.mj_offsetX;
    // 头部控件刚好出现的offsetY
    CGFloat happenOffsetX = - self.scrollViewOriginalInset.left;
    
    // 如果是向上滚动到看不见头部控件,直接返回
    // >= -> >
    if (offsetX > happenOffsetX) return;
    
    // 普通 和 即将刷新 的临界点 忘下拉,offsetX是负数,往右拉offsetX是负数
    CGFloat normal2pullingOffsetX = happenOffsetX - self.mj_w;
    CGFloat pullingPercent = (happenOffsetX - offsetX) / self.mj_w;
    if (self.scrollView.isDragging) {
        self.pullingPercent = pullingPercent;
        if (self.state == MJRefreshStateIdle && offsetX < normal2pullingOffsetX) {
            // 转为即将刷新状态
            self.state = MJRefreshStatePulling;
        } else if (self.state == MJRefreshStatePulling && offsetX >= normal2pullingOffsetX) {
            // 转为普通状态
            self.state = MJRefreshStateIdle;
        }
    }else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开
        // 开始刷新
        [self beginRefreshing];
    } else if (pullingPercent < 1) {
        self.pullingPercent = pullingPercent;
    }
}
- (void)scrollViewContentSizeDidChange:(NSDictionary *)change
{
    [super scrollViewContentSizeDidChange:change];
    self.mj_h = self.scrollView.mj_h;
    
    self.arrowImageView.mj_y = (self.mj_h-self.arrowImageView.image.size.height)/2.0;
    self.arrowImageView.mj_x = 15;
    self.indicator.frame = self.arrowImageView.frame;
    
    self.stateLbl.mj_x = self.arrowImageView.mj_w+15;
    self.stateLbl.mj_h = self.mj_h;
    self.mj_w = CGRectGetMidX(self.stateLbl.frame)+10;
    self.mj_x = - self.mj_w - self.ignoredScrollViewContentInsetLeft;
    NSLog(@"");
}
- (void)setState:(MJRefreshState)state
{
    MJRefreshCheckState
    self.stateLbl.text = self.stateTextDictM[@(state)];
    // 根据状态做事情
    if (state == MJRefreshStateIdle) {
        
        self.arrowImageView.hidden = NO;
        self.indicator.hidden = YES;
        [self.indicator stopAnimating];
        if (oldState == MJRefreshStatePulling) {
            [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{
                self.arrowImageView.transform = CGAffineTransformIdentity;
            }];
            
        }else{
            self.arrowImageView.transform = CGAffineTransformIdentity;
        }
        
        
        
        if (oldState != MJRefreshStateRefreshing) return;
        
        // 保存刷新时间
        [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:self.lastUpdatedTimeKey];
        [[NSUserDefaults standardUserDefaults] synchronize];
        
        // 恢复inset和offset
        [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{
            self.scrollView.mj_insetL += self.insetTDelta;
            
            // 自动调整透明度
            if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0;
        } completion:^(BOOL finished) {
            self.pullingPercent = 0.0;
            self.scrollView.mj_insetL -= self.mj_w;
            if (self.endRefreshingCompletionBlock) {
                self.endRefreshingCompletionBlock();
            }
        }];
    } else if (state == MJRefreshStateRefreshing) {
        dispatch_async(dispatch_get_main_queue(), ^{
            self.arrowImageView.hidden = YES;
            self.indicator.hidden = NO;
            [self.indicator startAnimating];
            [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{
                CGFloat left = self.scrollViewOriginalInset.left + self.mj_w;
                // 增加滚动区域top
                self.scrollView.mj_insetL = left;
                // 设置滚动位置
                //self.scrollView.mj_offsetX = -left;
                [self.scrollView setContentOffset:CGPointMake(-left, 0) animated:NO];
            } completion:^(BOOL finished) {
                [self executeRefreshingCallback];
            }];
        });
    }else if(state == MJRefreshStatePulling){
        self.arrowImageView.hidden = NO;
        self.indicator.hidden = YES;
        [self.indicator stopAnimating];
        [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{
            self.arrowImageView.transform = CGAffineTransformMakeRotation(0.000001 - M_PI);
        }];
    }
}
#pragma mark - 公共方法
- (void)endRefreshing
{
    dispatch_async(dispatch_get_main_queue(), ^{
        self.state = MJRefreshStateIdle;
    });
}

- (NSDate *)lastUpdatedTime
{
    return [[NSUserDefaults standardUserDefaults] objectForKey:self.lastUpdatedTimeKey];
}
- (NSMutableDictionary *)stateTextDictM
{
    if (_stateTextDictM == nil) {
        _stateTextDictM = [NSMutableDictionary dictionary];
        _stateTextDictM[@(MJRefreshStateIdle)] = @"右滑刷新数据";
        _stateTextDictM[@(MJRefreshStatePulling)] = @"释放刷新";
        _stateTextDictM[@(MJRefreshStateRefreshing)] = @"正在刷新";
    }
    return _stateTextDictM;
}
- (UILabel *)stateLbl
{
    if (_stateLbl == nil) {
        _stateLbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 20, 0)];
        _stateLbl.text = self.stateTextDictM[@(self.state)];
        _stateLbl.textColor = [UIColor blackColor];
        _stateLbl.font = [UIFont systemFontOfSize:10];
        _stateLbl.numberOfLines = 0;
        _stateLbl.textAlignment = NSTextAlignmentCenter;
    }
    return _stateLbl;
}
- (UIImageView *)arrowImageView
{
    if (_arrowImageView == nil) {
        _arrowImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"右滑"]];
    }
    return _arrowImageView;
}
- (UIActivityIndicatorView *)indicator
{
    if (_indicator == nil) {
        _indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
        _indicator.frame = self.arrowImageView.frame;
        _indicator.hidden = YES;
    }
    return _indicator;
}
@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,728评论 4 61
  • 嗯哼嗯哼蹦擦擦~~~ 转载自:https://github.com/Tim9Liu9/TimLiu-iOS 目录 ...
    philiha阅读 5,195评论 0 6
  • 一,本次绘画用宣纸,国画颜料,毛笔,勾线笔 二,起行。绘画功底好的话,可以直接起行,一般的话建议用铅笔淡淡的勾画轮...
    三古月甯阅读 1,187评论 6 8
  • 18-3 你有什么兴趣?你是如何培养你的兴趣的? 看到大家留言,爱钻研、爱画画、爱表达、爱手工都是兴趣。什么是兴趣...
    幸运的老师阅读 3,313评论 0 2
  • lmem阅读 1,290评论 0 1

友情链接更多精彩内容