iOS实现MJRefresh下拉刷新(上拉加载)使用详解
发布时间 - 2026-01-10 22:41:06 点击率:次下拉刷新控件目前比较火的有好几种,本人用过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张图片去模拟动画。<br><br>重写完<span class="s1">prepare方法,就可以实现动画了。<br><br></span>
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;
}
}
上拉刷新加载其实和下拉是同理,只不过区别就是:
self.tableView.mj_header 变成 self.tableView.mj_footer,后面的类也由
MJRefreshNormalHeader 变成 MJRefreshAutoNormalFooter。
实现原理是相同的。
下载源码:http://xiazai./201701/yuanma/MJRefresh_jb51.rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# mjrefresh下拉刷新
# ios下拉刷新实现原理
# ios
# 下拉刷新动画
# 举例讲解iOS中延迟加载和上拉刷新/下拉加载的实现
# iOS开发之UITableView与UISearchController实现搜索及上拉加载
# 下拉刷新实例代码
# ios基于MJRefresh实现上拉刷新和下拉加载动画效果
# iOS列表上拉(平滑加载数据)自动加载数据的问题解决
# 自定义
# 重写
# 回调
# 就会
# 在这里
# 我们可以
# 很简单
# 加载
# 就可以
# 自己的
# 临界值
# 是因为
# 不需要
# 适用于
# 更高
# 千万不要
# 只需要
# 用过
# 为例
# 要来
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何将凡科建站内容保存为本地文件?
如何在腾讯云服务器快速搭建个人网站?
音乐网站服务器如何优化API响应速度?
Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程
详解阿里云nginx服务器多站点的配置
如何确保FTP站点访问权限与数据传输安全?
魔方云NAT建站如何实现端口转发?
猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?
Laravel控制器是什么_Laravel MVC架构中Controller的作用与实践
Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面
如何在腾讯云免费申请建站?
Laravel API资源(Resource)怎么用_格式化Laravel API响应的最佳实践
Laravel怎么发送邮件_Laravel Mail类SMTP配置教程
Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)
济南网站建设制作公司,室内设计网站一般都有哪些功能?
Laravel如何编写单元测试和功能测试?(PHPUnit示例)
奇安信“盘古石”团队突破 iOS 26.1 提权
香港服务器建站指南:外贸独立站搭建与跨境电商配置流程
网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?
ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法
Laravel如何实现事件和监听器?(Event & Listener实战)
使用spring连接及操作mongodb3.0实例
Laravel如何配置中间件Middleware_Laravel自定义中间件拦截请求与权限校验【步骤】
Claude怎样写约束型提示词_Claude约束提示词写法【教程】
如何在阿里云购买域名并搭建网站?
jQuery validate插件功能与用法详解
Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】
在线制作视频网站免费,都有哪些好的动漫网站?
Laravel怎么实现模型属性的自动加密
JavaScript Ajax实现异步通信
,在苏州找工作,上哪个网站比较好?
如何实现建站之星域名转发设置?
黑客入侵网站服务器的常见手法有哪些?
Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程
Laravel如何处理CORS跨域请求?(配置示例)
Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比
UC浏览器如何设置启动页 UC浏览器启动页设置方法
DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解
网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?
如何用低价快速搭建高质量网站?
Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】
使用豆包 AI 辅助进行简单网页 HTML 结构设计
Laravel如何配置Horizon来管理队列?(安装和使用)
北京网站制作的公司有哪些,北京白云观官方网站?
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
微博html5版本怎么弄发语音微博_语音录制入口及时长限制操作【教程】
网站建设整体流程解析,建站其实很容易!
简历在线制作网站免费版,如何创建个人简历?
Laravel如何实现多对多模型关联?(Eloquent教程)
高性能网站服务器部署指南:稳定运行与安全配置优化方案

