博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS MJRefresh下拉刷新(上拉加载)使用详解
阅读量:5919 次
发布时间:2019-06-19

本文共 8185 字,大约阅读时间需要 27 分钟。

下拉刷新控件目前比较火的有好几种,本人用过MJRefresh 和 SVPullToRefresh,相对而言,前者比后者可定制化、拓展新都更高一点。

因此本文着重讲一下MJRefresh的简单用法。

 

导入项目:

  • cocoapods导入:pod 'MJRefresh'
  • 手动导入:
    • MJRefresh文件夹中的所有文件拽入项目中
    • 导入主头文件:#import "MJRefresh.h"

 

 

下拉刷新:

广泛性分为6种使用场景,分别对应:默认、动画图片、隐藏时间、隐藏时间和状态、自定义文字说明、以及自定义刷新控件。

 

下面就各种场景分别讲一下:

1、默认场景

 

 包含刷新菊花、下拉说明、时间

使用代码:

#pragma mark UITableView + 下拉刷新 默认- (void)example01{    __weak __typeof(self) weakSelf = self;        // 设置回调(一旦进入刷新状态就会调用这个refreshingBlock)    self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{        [weakSelf loadNewData];    }];        // 马上进入刷新状态    [self.tableView.mj_header beginRefreshing];}

  

2、使用动画图片

 

 

PS:这里的动画并不是用gif实现的,而是利用序列帧(即若干图片组成一个不同状态下的图片数组,然后根据位置显示不同图片)去展现。

#pragma mark UITableView + 下拉刷新 动画图片- (void)example02{    // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)    self.tableView.mj_header = [MJChiBaoZiHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)];        // 马上进入刷新状态    [self.tableView.mj_header beginRefreshing];}

这里用大众点评吃包子图片为例,新建一个自定义类 MJChiBaoZiHeader,继承:MJRefreshGifHeader

#import "MJRefreshGifHeader.h" 

@interface MJChiBaoZiHeader : MJRefreshGifHeader 

@end

然后重写prepare方法,代码:

- (void)prepare{    [super prepare];        // 设置普通状态的动画图片    NSMutableArray *idleImages = [NSMutableArray array];    for (NSUInteger i = 1; i<=60; i++) {        UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_anim__000%zd", i]];        [idleImages addObject:image];    }     [self setImages:idleImages forState:MJRefreshStateIdle];        // 设置即将刷新状态的动画图片(一松开就会刷新的状态)    NSMutableArray *refreshingImages = [NSMutableArray array];    for (NSUInteger i = 1; i<=3; i++) {        UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_loading_0%zd", i]];        [refreshingImages addObject:image];    }    [self setImages:refreshingImages forState:MJRefreshStatePulling];        // 设置正在刷新状态的动画图片    [self setImages:refreshingImages forState:MJRefreshStateRefreshing];}

关键点就是这里的两个图片数组,60是因为下拉控件默认拉动距离就是60距离,这里比较严谨,利用60张不同图片去对应每个距离点,当然实际中,我们可以缩减,不需要精确到每个距离点对应一张图片,这里个人自己决定。

这里需要先了解下,下拉的五种状态。如下:

/** 刷新控件的状态 */typedef NS_ENUM(NSInteger, MJRefreshState) {    /** 普通闲置状态 */    MJRefreshStateIdle = 1,    /** 松开就可以进行刷新的状态 */    MJRefreshStatePulling,    /** 正在刷新中的状态 */    MJRefreshStateRefreshing,    /** 即将刷新的状态 */    MJRefreshStateWillRefresh,    /** 所有数据加载完毕,没有更多的数据了 */    MJRefreshStateNoMoreData};

  

idleImages图片数组对应闲置下拉状态,表示下拉到临界值前的展示图片。
refreshingImages图片数组对应正在刷新时的动画展示图片,一般这里需要3~5张图片去模拟动画。 重写完prepare方法,就可以实现动画了。

3、下拉刷新 隐藏时间

 

 

这里与默认的区别就是不显示上次刷新时间,使用方法:

#pragma mark UITableView + 下拉刷新 隐藏时间- (void)example03{    // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)    MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)];        // 设置自动切换透明度(在导航栏下面自动隐藏)    header.automaticallyChangeAlpha = YES;        // 隐藏时间    header.lastUpdatedTimeLabel.hidden = YES;        // 马上进入刷新状态    [header beginRefreshing];        // 设置header    self.tableView.mj_header = header;}

 

4、下拉刷新 隐藏状态和时间

这个场景一般适用于只需要动画展示,简洁清爽,也是用的蛮多的。

同样,处理很简单。

#pragma mark UITableView + 下拉刷新 隐藏状态和时间- (void)example04{    // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)    MJChiBaoZiHeader *header = [MJChiBaoZiHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)];        // 隐藏时间    header.lastUpdatedTimeLabel.hidden = YES;    // 隐藏状态    header.stateLabel.hidden = YES;        // 马上进入刷新状态    [header beginRefreshing];        // 设置header    self.tableView.mj_header = header;}

  

5、下拉刷新 自定义文字

想自己DIY个性文字描述,一样很简单。

不管是文字text、文字大小、还是颜色都一句话搞定。

 

 

#pragma mark UITableView + 下拉刷新 自定义文字- (void)example05{    // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)    MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)];        // 设置文字    [header setTitle:@"快扯我,快点" forState:MJRefreshStateIdle];    [header setTitle:@"数据要来啦" forState:MJRefreshStatePulling];    [header setTitle:@"服务器正在狂奔 ..." forState:MJRefreshStateRefreshing];        // 设置字体    header.stateLabel.font = [UIFont systemFontOfSize:15];    header.lastUpdatedTimeLabel.font = [UIFont systemFontOfSize:14];    // 设置颜色    header.stateLabel.textColor = [UIColor redColor];    header.lastUpdatedTimeLabel.textColor = [UIColor grayColor];        // 马上进入刷新状态    [header beginRefreshing];        // 设置刷新控件    self.tableView.mj_header = header;}

  

6、下拉刷新 自定义刷新控件

上面的都不够玩,怎么办,没关系,还有最后一种更定制化的方法:自己加控件样式。

 

 

这里不限于任何控件,我们可以在头部的这片区域,尽情添加Subviews,但记住一点,高度千万不要吵过header高度(默认60)。

除了控件,甚至可以自己绘制动画等等。

实现原理:同样先自定义自己的类,继承 MJRefreshHeader

重写 prepare 方法,再重写 placeSubviews 方法 设置位置。

代码:

a、定义控件属性

@interface MJDIYHeader()@property (weak, nonatomic) UILabel *label;@property (weak, nonatomic) UISwitch *s;@property (weak, nonatomic) UIImageView *logo;@property (weak, nonatomic) UIActivityIndicatorView *loading;@end

b、重写prepare方法

#pragma mark 在这里做一些初始化配置(比如添加子控件)- (void)prepare{    [super prepare];        // 设置控件的高度    self.mj_h = 50;        // 添加label    UILabel *label = [[UILabel alloc] init];    label.textColor = [UIColor colorWithRed:1.0 green:0.5 blue:0.0 alpha:1.0];    label.font = [UIFont boldSystemFontOfSize:16];    label.textAlignment = NSTextAlignmentCenter;    [self addSubview:label];    self.label = label;        // 打酱油的开关    UISwitch *s = [[UISwitch alloc] init];    [self addSubview:s];    self.s = s;        // logo    UIImageView *logo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Logo"]];    logo.contentMode = UIViewContentModeScaleAspectFit;    [self addSubview:logo];    self.logo = logo;        // loading    UIActivityIndicatorView *loading = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];    [self addSubview:loading];    self.loading = loading;}

c、重写 placeSubviews 

#pragma mark 在这里设置子控件的位置和尺寸- (void)placeSubviews{    [super placeSubviews];    self.label.frame = self.bounds;        self.logo.bounds = CGRectMake(0, 0, self.bounds.size.width, 100);    self.logo.center = CGPointMake(self.mj_w * 0.5, - self.logo.mj_h + 20);        self.loading.center = CGPointMake(self.mj_w - 30, self.mj_h * 0.5);}

d、根据下拉位移,自定义不同位移的控件展示,比如显示不同文字,颜色等

#pragma mark 监听控件的刷新状态- (void)setState:(MJRefreshState)state{    MJRefreshCheckState;    switch (state) {        case MJRefreshStateIdle:            [self.loading stopAnimating];            [self.s setOn:NO animated:YES];            self.label.text = @"赶紧下拉吖(开关是打酱油滴)";            break;        case MJRefreshStatePulling:            [self.loading stopAnimating];            [self.s setOn:YES animated:YES];            self.label.text = @"赶紧放开我吧(开关是打酱油滴)";            break;        case MJRefreshStateRefreshing:            [self.s setOn:YES animated:YES];            self.label.text = @"加载数据中(开关是打酱油滴)";            [self.loading startAnimating];            break;        default:            break;    }}

 

 

上拉刷新:

上拉刷新加载和下拉很类似,这里我只讲几点小注意点:

1、MJRefreshBackNormalFooter 和 MJRefreshAutoNormalFooter都能实现上拉加载,

不过两者有点区别:前者的上拉区域在tableview的底部,后者是紧跟在数据下方。这个大家可以视情况选择。

 

2、如果选择的MJRefreshAutoNormalFooter,可能会遇到一个:“点击或上拉加载更多”会一直存在的问题,如何去掉呢?

解决办法:

1、修改源码,在MJRefreshConst.m里更改这句话:

NSString *const MJRefreshAutoFooterIdleText = @"";

2、设置isAutomaticallyChangeAlpha属性为yes。

参考代码:

let mjfoot = MJRefreshBackNormalFooter {             if weakself?.lastId == -1 || weakself?.pageIndex == -1{                weakself?.tableView.mj_footer.endRefreshingWithNoMoreData()                return            }                        weakself?.requestData()        }        mjfoot?.setTitle("没有更多数据了", for: .noMoreData)        mjfoot?.isAutomaticallyChangeAlpha = true        tableView.mj_footer = mjfoot

 

3、设置没有数据时,不显示上拉加载说明

func setMJFooterVisible() {        if ELList.count <= 0 {            tableView.mj_footer.isHidden = true        }else{            tableView.mj_footer.isHidden = false        }  }

 

 

4、修改刷新的提示语,这点下拉刷新和上拉加载都适用 ,再说明一下:

这种需要先初始化一个header或footer,再设置settitle方法就好了。

[header setTitle:@"快扯我,快点" forState:MJRefreshStateIdle];    [header setTitle:@"数据要来啦" forState:MJRefreshStatePulling];    [header setTitle:@"服务器正在狂奔 ..." forState:MJRefreshStateRefreshing];

 

 

下载源码:

 

enjoy~

  

转载地址:http://irfvx.baihongyu.com/

你可能感兴趣的文章
jQuery全选反选全不选
查看>>
HD-ACM算法专攻系列(12)——Integer Inquiry
查看>>
IIS - 自动申请、部署Let's Encrypt的免费SSL证书(让网站实现HTTPS协议)
查看>>
《CLR via C#》笔记——可空值类型
查看>>
微信公众平台消息接口星标功能
查看>>
JavaScript秘密花园 - scope, namespace, constructor, equality and comparisons
查看>>
Android数据存储——2.文件存储_C_DOM解析XML文档
查看>>
阿里云maven仓库
查看>>
10分钟读懂html5 多了啥?
查看>>
VS2010 旗舰版序列号
查看>>
【转录】原来Github上的README.md文件这么有意思——Markdown语言详解
查看>>
Node.js之操作文件系统(一)
查看>>
相克宗 藏民家
查看>>
ajex 相关参数
查看>>
02-CSS基础与进阶-day9_2018-09-12-21-44-58
查看>>
POJ 2391.Ombrophobic Bovines (最大流)
查看>>
ASP.NET MVC 4 (九) 模型绑定
查看>>
Python遍历List集合四种方法
查看>>
HDU 4438 概率 多个情况下的数学期望
查看>>
金融投资的9个环节(不一定适合任何人)
查看>>