https://www.cnblogs.com/yajunLi/p/5735990.html

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

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

导入项目:

  • cocoapods导入:pod 'MJRefresh'

手动导入:

  • MJRefresh文件夹中的所有文件拽入项目中

  • 导入主头文件:#import "MJRefresh.h"

下拉刷新:

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

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

1、默认场景

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

使用代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

#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实现的,而是利用序列帧(即若干图片组成一个不同状态下的图片数组,然后根据位置显示不同图片)去展现。

1

2

3

4

5

6

7

8

9

#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方法,代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

- (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张不同图片去对应每个距离点,当然实际中,我们可以缩减,不需要精确到每个距离点对应一张图片,这里个人自己决定。

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

1

2

3

4

5

6

7

8

9

10

11

12

13

/** 刷新控件的状态 */

typedef NS_ENUM(NSInteger, MJRefreshState) {

    /** 普通闲置状态 */

    MJRefreshStateIdle = 1,

    /** 松开就可以进行刷新的状态 */

    MJRefreshStatePulling,

    /** 正在刷新中的状态 */

    MJRefreshStateRefreshing,

    /** 即将刷新的状态 */

    MJRefreshStateWillRefresh,

    /** 所有数据加载完毕,没有更多的数据了 */

    MJRefreshStateNoMoreData

};

  

1

idleImages图片数组对应闲置下拉状态,表示下拉到临界值前的展示图片。

1

refreshingImages图片数组对应正在刷新时的动画展示图片,一般这里需要3~5张图片去模拟动画。<br><br>重写完<span class="s1">prepare方法,就可以实现动画了。<br><br></span>

3、下拉刷新 隐藏时间

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

#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、下拉刷新 隐藏状态和时间

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

同样,处理很简单。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

#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、文字大小、还是颜色都一句话搞定。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

#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、定义控件属性

1

2

3

4

5

6

@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方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

#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

1

2

3

4

5

6

7

8

9

10

11

12

#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、根据下拉位移,自定义不同位移的控件展示,比如显示不同文字,颜色等

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

#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()

  1. 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];

iOS MJ 刷新 一些自定义相关推荐

  1. IOS 类似抖音下拉刷新与自定义上拉加载

    IOS 类似抖音下拉刷新与自定义上拉加载 最近UICollectionView中使用了pageEnabled,MJRresh直接使用时出现偏移.这里就暂时考虑简单的做法. 首先考虑在UICollect ...

  2. iOS 11 MJ刷新异常,上拉加载出现跳动刷新问题

    MJ刷新异常,上拉加载出现跳动刷新问题: 解决办法:初始化的时候增加以下代码(tableView和collectionView类似) if (@available(iOS11.0, *)) {_tab ...

  3. iOS开发多线程篇—自定义NSOperation

    iOS开发多线程篇-自定义NSOperation 一.实现一个简单的tableView显示效果 实现效果展示: 代码示例(使用以前在主控制器中进行业务处理的方式) 1.新建一个项目,让控制器继承自UI ...

  4. Android仿IOS解锁密码界面-自定义view系列(6)

    Android仿IOS解锁密码界面-自定义view系列 功能简介 主要实现步骤-具体内容看github项目里的代码 xml相关属性设置 Android Studio 代码 Android技术生活交流 ...

  5. iOS开发那些事--自定义单元格实现

    自定义单元格 当苹果公司提供给的单元格样式不能我们的业务需求的时候,我们需要自定义单元格.在iOS 5之前,自定义单元格可以有两种实现方式:代码实现和用xib技术实现.用xib技术实现相对比较简单,创 ...

  6. Android手机teams,在iOS和Android上自定义Microsoft Teams体验的三种最佳方法

    以下是您可以在iOS和Android上自定义Microsoft Teams应用程序以使其成为自己的三种方法 1. 开启黑暗模式,以便iOS和Android上的小组中的消息和其他内容更易于理解和阅读 2 ...

  7. iOS - UIRefreshControl 刷新数据

    前言 NS_CLASS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED @interface UIRefreshControl : UIControl 1.UIRefresh ...

  8. ios 动画 隐藏tabbar_iOS_自定义转场TabBar的隐藏动画

    摘要 实现同iOS 11 App Store Today相似的转场效果.本文尝试解决转场(Transition)过程中TabBar的隐藏(向下滑出屏幕). tabbar_ani_slow.gif 遇到 ...

  9. iOS开发使用UIKeyInput自定义密码输入框

    前言 开发中很多地方都会遇到密码输入,这时候往往需要根据UI设计自定义.这里遵守UIKeyInput,实现协议中的方法,让自定义View可以进行文字输入:再通过func draw(_ rect: CG ...

最新文章

  1. 简单又好看的按钮,扁平化按钮。
  2. firefox浏览器不能使用window.close的解决方案
  3. 通过电机编码器AB相输出确定电机转向
  4. python利用递归函数实现斐波那契数列_Python递归及斐波那契数列
  5. Tcpdump 详解
  6. CF1054D-Changing Array【贪心】
  7. 《DBNotes: Buffer Pool对于缓冲页的链表式管理》
  8. pxe安装linux后命令不可用,pxe自动安装linux
  9. 最新编程语言排名:Python超Java、JS保持领头羊
  10. 鸿蒙系统即将发布,华为鸿蒙商标获转让
  11. php+oracle新增数据类型,Oracle 修改某个字段的数据类型三种方式
  12. java 日期for循环_java for循环的时候增加循环体的长度是不是不太好的?
  13. 服务器虚拟化的毕业设计,云桌面技术研究与应用毕业设计论文+开题报告+翻译+源码...
  14. 用户态文件系统fuse学习
  15. [转载]Oracle监听器安装与设置(2)
  16. configure/make的shared object参数
  17. 汇编语言程序设计实验报告
  18. 联想官方一键关闭Win10Defender、关闭Win10自动更新工具
  19. 双下划线一粗一细怎么加_word 下划线 一粗一细
  20. C++ opencv显示fps帧率

热门文章

  1. IIS6 + Resin3.1.x 的不爽之处
  2. 东北农业大学计算机科学与技术复试名单,复试通知来了!150余所高校已发布最新复试信息!...
  3. HTTP请求网页(包括HTTPS)
  4. python实现井字棋
  5. 虚拟机中的centos在nat模式下连不上外网
  6. 动态规划-拔萝卜问题
  7. C语言计算圆柱的表面积 体积
  8. 谈谈工作 - 神州数码篇
  9. 中科院、华为等提出Vision GNN,只使用图神经网络进行视觉任务
  10. 免费的小程序微商城系统它不香吗?