iOS MJRefresh下拉刷新(上拉加载)使用详解
下拉刷新控件目前比较火的有好几种,本人用过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 == - || weakself?.pageIndex == -{
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 <= {
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];
下载源码:https://github.com/CoderMJLee/MJRefresh
enjoy~
iOS MJRefresh下拉刷新(上拉加载)使用详解的更多相关文章
- Android 下拉刷新上啦加载SmartRefreshLayout + RecyclerView
在弄android刷新的时候,可算是耗费了一番功夫,最后发觉有现成的控件,并且非常好用,这里记录一下. 原文是 https://blog.csdn.net/huangxin112/article/de ...
- SwipeRefreshLayout实现下拉刷新上滑加载
1. 效果图 2.RefreshLayout.java package myapplication.com.myapplication; import android.content.Context; ...
- 移动端下拉刷新上拉加载-mescroll.js插件
最近无意间看到有这么一个上拉刷新下拉加载的插件 -- mescroll.js,个人感觉挺好用的,官网地址是:http://www.mescroll.com 然后我就看了一下文档,简单的写了一个小dem ...
- 使用MJRefresh自定义下拉刷新,上拉加载动画
有时候我们需要自己设置下拉刷新,上拉加载动画的实现,这里主要是记录下使用MJRefresh自定义下拉刷新,上拉加载动画..... 下拉刷新我们只需要继承MJRefreshGifHeader即可: 实现 ...
- 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载
title: 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载 tags: -RecyclerView,下拉刷新,上拉加载更多 grammar_cjkRuby: true - ...
- ListView实现Item上下拖动交换位置 并且实现下拉刷新 上拉加载更多
ListView实现Item上下拖动交换位置 并且实现下拉刷新 上拉加载更多 package com.example.ListViewDragItem; import android.app.Ac ...
- [ionic开源项目教程] - 第7讲 实现下拉刷新上拉加载ion-refresher和ion-infinite-scroll
第7讲 实现下拉刷新上拉加载ion-refresher和ion-infinite-scroll 1.将tab1.html的代码改为如下: <ion-content> <ion-ref ...
- JS+CSS实现的下拉刷新/上拉加载插件
闲来无事,写了一个当下比较常见的下拉刷新/上拉加载的jquery插件,代码记录在这里,有兴趣将代码写成插件与npm包可以留言. 体验地址:http://owenliang.github.io/pull ...
- 基于SwiperJs的H5/移动端下拉刷新上拉加载更多的效果
最早时,公司的H5项目中曾用过点击一个"加载更多"的DOM元素来实现分页的功能,后来又用过网上有人写的一个上拉加载更多的插件,那个插件是页面将要滚动到底部时就自动请求数据并插入到页 ...
- ListView下拉刷新上拉加载更多实现
这篇文章将带大家了解listview下拉刷新和上拉加载更多的实现过程,先看效果(注:图片中listview中的阴影可以加上属性android:fadingEdge="none"去掉 ...
随机推荐
- Spark集群 + Akka + Kafka + Scala 开发(3) : 开发一个Akka + Spark的应用
前言 在Spark集群 + Akka + Kafka + Scala 开发(1) : 配置开发环境中,我们已经部署好了一个Spark的开发环境. 在Spark集群 + Akka + Kafka + S ...
- python 实时遍历日志文件
首先尝试使用 python open 遍历一个大日志文件, 使用 readlines() 还是 readline() ? 总体上 readlines() 不慢于python 一次次调用 readlin ...
- maven 跳过测试 打包 及上传命令
[main] ERROR org.apache.maven.cli.MavenCli - Failed to execute goal org.apache.maven.plugins:maven-s ...
- 说说IT技术团队招聘那点事
因为近来由于新项目的需要,各种招聘比较多,几乎每周都要面试几个人,顺便对以前的面试和带开发经验进行简单的总结 1.首先负责招聘的人一定得是自己团队的人,而且在招聘的时候一定要想清楚目标候选人进来的职责 ...
- 用fasterjson需要注意的地方
JSONArray.toJSONString()之后不是一个json,而是json中的一个数组 JSONObject是一个json JSON.toJSONString()不可多次使用,因为每次调用JS ...
- 使用 WordPress 插件模板开发高质量插件
WordPress 插件样板是标准化的,有组织的,面向对象的基础,用于构建高品质的 WordPress 插件.样板遵循编码标准和文件标准,所以你不必自己学习这些,根据注释编写代码即可. 官方网站 ...
- heX——基于 HTML5 和 Node.JS 开发桌面应用
heX 是网易有道团队的一个开源项目,允许你采用前端技术(HTML,CSS,JavaScript)开发桌面应用软件的跨平台解决方案.heX 是你开发桌面应用的一种新的选择,意在解决传统桌面应用开发中繁 ...
- Jquery中的日历插件
这个插件很简单:只需要在HTML代码中引入插件如下,CLASS名和click事件函数固定! <!doctype html> <html lang="en"> ...
- CSS3绘制六边形
因为很简单,所以先总结一下:使用CSS3绘制六边形主要使用伪类:before和:after在源元素之前和之后再绘制两个元素,并利用css3的边框样式,将这两个元素变成三角形放置在源元素的两端即可. ( ...
- PCAP过滤器
PCAP-FILTER NAME pcap-filter-packet filter syntax DESCRIPTION pcap_compile() 将字符串编译成过滤器程序. 合理的过滤器程序可 ...