03-项目中的数据刷新

  • 项目中经常会用到上拉下拉刷新,通常使用<MJRefresh>框架
  • 一般公司都会对自己app的上拉下拉刷新作特性化定制,而且全局多处用到.所以需要对自定义的上拉下拉刷新进行封装

代码如下(文字效果)

下拉刷新封装 (继承MJRefreshNormalHeader)

.h文件

#import <MJRefresh/MJRefresh.h>

@interface XMGRefreshHeader : MJRefreshNormalHeader

@end

.m文件

#import "XMGRefreshHeader.h"

@interface XMGRefreshHeader()
/** logo */
@property (nonatomic, weak) UIImageView *logo;
@end

@implementation XMGRefreshHeader

/**
 *  初始化
 */
- (void)prepare
{
    [super prepare];
    
    self.automaticallyChangeAlpha = YES;
// 修改时间文字的颜色
    self.lastUpdatedTimeLabel.textColor = [UIColor orangeColor];
// 修改刷新状态的颜色
    self.stateLabel.textColor = [UIColor orangeColor];
// 设置state状态下的文字 
    [self setTitle:@"赶紧下拉吧" forState:MJRefreshStateIdle];
    [self setTitle:@"赶紧松开吧" forState:MJRefreshStatePulling];
    [self setTitle:@"正在加载数据..." forState:MJRefreshStateRefreshing];
// 隐藏时间
    //    self.lastUpdatedTimeLabel.hidden = YES;
// 隐藏刷新状态
    //    self.stateLabel.hidden = YES;
// 添加控件
     [self addSubview:[[UISwitch alloc] init]];
   
// 添加logo 
    UIImageView *logo = [[UIImageView alloc] init];
    logo.image = [UIImage imageNamed:@"bd_logo1"];
    [self addSubview:logo];
    self.logo = logo;
}

/**
 *  摆放子控件
 */
- (void)placeSubviews
{
    [super placeSubviews];
    
    self.logo.xmg_width = self.xmg_width;
    self.logo.xmg_height = 50;
    self.logo.xmg_x = 0;
    self.logo.xmg_y = - 50; // 自己控制
}

上拉刷新封装(继承MJRefreshAutoNormalFooter)

.h文件

#import <MJRefresh/MJRefresh.h>

@interface XMGRefreshFooter : MJRefreshAutoNormalFooter

@end

.m文件

#import "XMGRefreshFooter.h"

@implementation XMGRefreshFooter

- (void)prepare
{
    [super prepare];
    
    self.stateLabel.textColor = [UIColor redColor];
    
    [self addSubview:[UIButton buttonWithType:UIButtonTypeContactAdd]];
    
    // 刷新控件出现一半就会进入刷新状态
//    self.triggerAutomaticallyRefreshPercent = 0.5;
    
    // 不要自动刷新
//    self.automaticallyRefresh = NO;
}

@end

项目中使用

@interface XMGAllViewController ()
/** 所有的帖子数据 */
@property (nonatomic, strong) NSMutableArray<XMGTopic *> *topics;
/** 下拉刷新的提示文字 */
@property (nonatomic, weak) UILabel *label;
/** maxtime : 用来加载下一页数据 */
@property (nonatomic, copy) NSString *maxtime;
/** 任务管理者 */
@property (nonatomic, strong) AFHTTPSessionManager *manager;
@end
- (AFHTTPSessionManager *)manager
{
    if (!_manager) {
        _manager = [AFHTTPSessionManager manager];
    }
    return _manager;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    [self setupRefresh];
}

// 刷新
- (void)setupRefresh
{
    self.tableView.mj_header = [XMGRefreshHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewTopics)];
    // 希望一进来就刷新
    [self.tableView.mj_header beginRefreshing];

    self.tableView.mj_footer = [XMGRefreshFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreTopics)];
}

#pragma mark - 数据加载
- (void)loadNewTopics
{
    // 取消所有请求
   [self.manager.tasks makeObjectsPerformSelector:@selector(cancel)];
    // 参数
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    params[@"a"] = @"list";
    params[@"c"] = @"data";
    
    // 发送请求
    [[AFHTTPSessionManager manager] GET:@"http://api.budejie.com/api/api_open.php" parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
        // 存储maxtime(方便用来加载下一页数据)
        self.maxtime = responseObject[@"info"][@"maxtime"];
        
        // 字典数组 -> 模型数组
        self.topics = [XMGTopic mj_objectArrayWithKeyValuesArray:responseObject[@"list"]];
        
        // 刷新表格
        [self.tableView reloadData];        
        // 让[刷新控件]结束刷新
        [self.tableView.mj_header endRefreshing];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        XMGLog(@"请求失败 - %@", error);
        
        // 让[刷新控件]结束刷新
        [self.tableView.mj_header endRefreshing];
    }];
}

- (void)loadMoreTopics
{
    // 取消所有的请求
   [self.manager.tasks makeObjectsPerformSelector:@selector(cancel)];
    // 参数
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    params[@"a"] = @"list";
    params[@"c"] = @"data";
    params[@"maxtime"] = self.maxtime;
    
    // 发送请求
    [[AFHTTPSessionManager manager] GET:@"http://api.budejie.com/api/api_open.php" parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
        // 存储这页对应的maxtime
        self.maxtime = responseObject[@"info"][@"maxtime"];
        
        // 字典数组 -> 模型数组
        NSArray<XMGTopic *> *moreTopics = [XMGTopic mj_objectArrayWithKeyValuesArray:responseObject[@"list"]];
        [self.topics addObjectsFromArray:moreTopics];
        
        // 刷新表格
        [self.tableView reloadData];
        
        // 让[刷新控件]结束刷新
        [self.tableView.mj_footer endRefreshing];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        XMGLog(@"请求失败 - %@", error);
        
        // 让[刷新控件]结束刷新
        [self.tableView.mj_footer endRefreshing];
    }];
}

拓展分析

1. addObject:和addObjectsFromArray:的区别

self.topics = @[20, 19, 18]
moreTopics = @[17, 16, 15]

self.topics = @[20, 19, 18, @[17, 16, 15]]
[self.topics addObject:moreTopics];

self.topics = @[20, 19, 18, 17, 16, 15]
[self.topics addObjectsFromArray:moreTopics];

2. 常见分页方法

F1799B71-E97E-4337-8D9E-B18CCDEA4C5A.png

方法一:
缺点:可能加载重数据

方法二:
大多数公司采用的方法
原理:明确的告诉服务器我数据加载到哪

分页在项目示例中的解析

在下拉的 - (void)loadNewTopics 方法中 ,存储一下它的maxtime

// 存储maxtime(方便用来加载下一页数据)
self.maxtime = responseObject[@"info"][@"maxtime"];

在上拉 - (void)loadMoreTopics 中要传maxtime给后台,同时maxtime的值根据不断地恶上拉要不断更新,所以在上拉后,将后台返回的maxtime不断存储下来

// 存储这页对应的maxtime
self.maxtime = responseObject[@"info"][@"maxtime"];

3. 上拉下拉刷新出现的一些问题

  • 当上拉下拉同时出现时,会出现数据漏掉问题
29891B6C-6FD6-4095-9404-68F4574C37B4.png

解决:
上拉时,取消其它的所有请求 ,同时取消刷新控件
下拉时,取消其它的所有请求 ,同时取消刷新控件

// 所有的任务被任务管理者统一管理
// 此句代码的意思就是取消其它所有的请求
//  一个请求任务被取消了(cancel), 会自动调用AFN请求的failure这个block
// 所以不需要再单独去写取消刷新控件
 [self.manager.tasks makeObjectsPerformSelector:@selector(cancel)];

4. 子类化AFHTTPSessionManager

需求:因为有可能项目中多地方使用,并且会做一些统一化设置,所以将其抽出一个子类,方便项目中使用(官方建议如此使用)

代码如下:

#import <AFNetworking/AFNetworking.h>

@interface XMGHTTPSessionManager : AFHTTPSessionManager

@end
#import "XMGHTTPSessionManager.h"

@implementation XMGHTTPSessionManager

- (instancetype)initWithBaseURL:(NSURL *)url
{
    if (self = [super initWithBaseURL:url]) {
//        self.securityPolicy.validatesDomainName = NO;
//        self.responseSerializer = nil;
//        self.requestSerializer = nil;
    }
    return self;
}

@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容

  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,693评论 2 59
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,522评论 25 707
  • 11月16日,据泰国媒体报道,泰国、LaSalle、JLL的董事Jones Lang LaSalle(J.J.L....
    yoawmjytib阅读 217评论 0 0
  • 姓名:周立 zhou li 公司:宁波大发化纤有限公司 【日精进打卡第42天】 【知~学习】 (六项精进)大纲背...
    周立zhouli阅读 152评论 0 0
  • 晚上和前任吃饭 餐桌上互道彼此近况 三言两语竟说到从前 你变了好多,前任直言不讳。 从前你性情暴躁 总发脾气 三天...
    鱼啦啦8阅读 263评论 0 0