美文网首页
03-项目中的数据刷新

03-项目中的数据刷新

作者: 小胖子2号 | 来源:发表于2018-11-08 16:17 被阅读4次
    • 项目中经常会用到上拉下拉刷新,通常使用<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
    

    相关文章

      网友评论

          本文标题:03-项目中的数据刷新

          本文链接:https://www.haomeiwen.com/subject/iaswxqtx.html