百思不得姐数据刷新数据部分(七)

一 刷新功能图和内部计算原理图

1 刷新功能图:

2 内部计算原理图

二 解析步骤

1 分析整个精华模块

2 真实数据请求部分

3 模型

4 先添加尾部刷新控件

5 再添加头部刷新控件

6 处理刷新业务逻辑

7 知识点补充

三 分析模块

1 从一个完整的app中可以看出,在精华模块中处于全部标题的部分数据包括了其它几部分的数据,内部有视频;声音;图片和段子,所以我们只需要将”全部”做好,就能很快的搞定其它模块了.

四 真实数据请求

1 大致步骤:

—-> 1 查看百思不得姐该部分的接口文档,获取URL.

—-> 2 查看接口文档中哪些是需要的请求参数(在百思不得姐的接口文档中:后面表明了ture是必须要的请求参数)

—-> 3 查看接口文档,请求方式是什么?这里是GET请求.

—-> 4 zing共请求数据分三大步骤:1> 创建会话管理者 2> 设置请求参数 3> 发送请求.

2 需要导入的框架

#import <AFNetworking.h>

#import <MJExtension/MJExtension.h>

#import <SVProgressHUD.h>

3 代码部分:加载更多数据;加载最新数据

—> 3.1 加载更多帖子

#pragma mark - 加载更多的帖子数
- (void)setUpMoreTopics
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //设置请求参数
        NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
        //包装请求参数
        parameters[@"a"] = @"list";
        parameters[@"c"] = @"data";
        parameters[@"type"] = @"31";
        parameters[@"maxtime"] = self.maxtime;
        //发送请求
        [[AFHTTPSessionManager manager] GET:XFJ_requestURL parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            //取出info中的maxtime
            self.maxtime = responseObject[@"info"][@"maxtime"];
            //字典数组转模型数组(装入可变数组中)
            NSArray *arrayTopics = [XFJItem mj_objectArrayWithKeyValuesArray:responseObject[@"list"]];
            //将模型添加到装数组的模型中
            [self.item addObjectsFromArray:arrayTopics];
            //写入plist文件
            [responseObject writeToFile:@"/Users/xiaofeng/Desktop/New.plist" atomically:YES];
            //刷新tableView
            [self.tableView reloadData];
            //尾部结束刷新
            [self footerEndRefresh];
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            //尾部刷新数据失败也需要调用
            [self footerEndRefresh];
            //如果用户直接取消任务,来到failure中不需要提醒信息
            if (error.code == NSURLErrorCancelled) {
                return ;
            }
            //提醒用户刷新失败
            [SVProgressHUD showErrorWithStatus:@"网络繁忙,请稍后再试..."];
        }];
    });
}

—-> 3.2 加载最新的数据

#pragma mark - 加载最新的帖子数
- (void)setLoadNews
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //设置请求参数
        NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
        //包装请求体
        parameters[@"a"] = @"list";
        parameters[@"c"] = @"data";
        parameters[@"type"] = @"31";
        //发送请求
        [[AFHTTPSessionManager manager] GET:XFJ_requestURL parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            //取出info中的maxtime
            self.maxtime = responseObject[@"info"][@"maxtime"];
            //字典数组转模型数组
            self.item = [XFJItem mj_objectArrayWithKeyValuesArray:responseObject[@"list"]];
            [responseObject writeToFile:@"/Users/xiaofeng/Desktop/New1.plist" atomically:YES];
            //刷新
            [self.tableView reloadData];
            //结束刷新
            [self headerEndRefresh];
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            //刷新失败了也需要结束
            [self headerEndRefresh];
            //如果用户直接取消任务,来到failure中不需要提醒信息
            if (error.code == NSURLErrorCancelled) {
                return ;
            }
            //提醒用户刷新失败
            [SVProgressHUD showErrorWithStatus:@"网络繁忙,请稍后再试..."];
        }];
    });
}

五 模型

1 模型中的数据部分选择所有模块的公共部分作为属性

2 代码:

/**
 *  踩(hate)
 */
@property (nonatomic, assign) NSInteger cai;
/**
 *  顶(love)
 */
@property (nonatomic, assign) NSInteger love;
/**
 *  帖子描述
 */
@property (nonatomic, strong) NSString *text;
/**
 *  发帖时间
 */
@property (nonatomic, strong) NSString *passtime;
/**
 *  用户名
 */
@property (nonatomic, strong) NSString *name;
/**
 *  转发
 */
@property (nonatomic, assign) NSInteger repost;
/**
 *  转发数
 */
@property (nonatomic, assign) NSInteger comment;
/**
 *  头像
 */
@property (nonatomic, strong) NSString *profile_image;

六 添加尾部刷新控件

1 这里采用UILabel作为刷新的控件(也可以采用UIView)

2 注意刷新控件的添加位置(可以通过内部计算原理图来添加)

3 代码:

#pragma mark - 创建刷新的UILabel
- (void)setUpRefresh
{
    //上拉刷新控件
    //创建Label
    UILabel *refreshLabel = [[UILabel alloc] init];
    //设置label文字
    refreshLabel.text = @"上拉加载更多数据";
    //设置颜色
    refreshLabel.backgroundColor = [UIColor redColor];
    //设置文字的位置
    refreshLabel.textAlignment = NSTextAlignmentCenter;
    //设置文字颜色
    refreshLabel.textColor = [UIColor whiteColor];
    //设置高度
    refreshLabel.XFJ_Height = 35;
    //添加到footerView
    self.tableView.tableFooterView = refreshLabel;
    //赋值
    self.refreshLabel = refreshLabel;

    //下拉刷新控件
    [self setTitleRefresh];
}

七 底部刷新控件的业务逻辑

1 由于我们需要时刻的监听用户拖拽tableView的时候,来显示刷新控件的显示状态.因为UITableView是继承UIScrollView的,所以也同时拥有了UIScrollView中的方法.

2 监听用户拖动的时候调用

#pragma mark - 代理方法(拖动的时候调用)
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    //调用尾部方法
    [self dealFooter];
    //调用头部方法
    [self dealHeader];
}

3 处理用户往上拖拽的时候刷新条的业务逻辑

#pragma mark - footer处理尾部刷新拖动的时候逻辑
- (void)dealFooter
{
    if (self.item.count == 0) return;
    if (self.isFooterRefresh) return;
    //计算偏移量
    CGFloat offset = self.tableView.contentSize.height + self.tableView.contentInset.bottom - self.tableView.XFJ_Height;
    //判断
    if (self.tableView.contentOffset.y >= offset) {

        //开始刷新尾部数据
        [self footerBeginRefresh];
    }
}

4 tableView开始刷新部分

#pragma mark - footer开始刷新
- (void)footerBeginRefresh
{
    //如果尾部正在刷新就直接返回
    if (self.isFooterRefresh) return;
    //是否刷新数据
    self.footerRefresh = YES;
    //修改label文字
    self.refreshLabel.text = @"正在加载更多数据...";
    //修改label背景颜色
    self.refreshLabel.backgroundColor = [UIColor blueColor];
    //上拉刷新加载更多帖子
    [self setUpMoreTopics];
}

5 tableView结束刷新部分

#pragma mark - footer结束刷新
- (void)footerEndRefresh
{
    //结束刷新
    self.footerRefresh = NO;
    //恢复背景颜色
    self.refreshLabel.backgroundColor = [UIColor redColor];
    //恢复文字
    self.refreshLabel.text = @"上拉加载更多数据";
}

八 顶部刷新控件的业务逻辑

1 创建顶部刷新条

2 注意添加的位置

3 代码部分:

#pragma mark - 创建下拉刷新控件
- (void)setTitleRefresh
{
    //创建label
    UILabel *header = [[UILabel alloc] init];
    //设置背景颜色
    header.backgroundColor = [UIColor redColor];
    //设置文字颜色
    header.textColor = [UIColor whiteColor];
    //设置文字
    header.text = @"下拉加载跟多数据";
    //设置尺寸
    header.XFJ_Height =  50;
    //位置
    header.XFJ_Y = - header.XFJ_Height;
    //宽度
    header.XFJ_Width = self.tableView.XFJ_Width;
    //添加
    [self.tableView addSubview:header];
    //设置文字居中
    header.textAlignment = NSTextAlignmentCenter;
    //赋值
    self.header = header;
    //启动程序需要刷新
    [self headerBeginRefresh];
}

4 监听用户往下拖动tableView,刷新内容的监听(使用代理方法)

—-> 4.1 用户停止拖动的时候调用
#pragma mark - 拖动停止的时候调用
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    //如果头部正在刷新就不要刷新了
    if (self.isHeaderRefresh) return;
    //计算偏移量
    CGFloat offset = - (self.tableView.contentInset.top + self.header.XFJ_Height);
    //判断(通过判断偏移量来改变刷新控件上的文字的显示)
    if (self.tableView.contentOffset.y <= offset) {
        //开始刷新
        [self headerBeginRefresh];
    }
}
—-> 4.2 用户拖动的时候调用处理业务逻辑
#pragma mark - header处理头部逻辑
- (void)dealHeader
{
    //如果header还没有被创建的话就直接返回
    if (self.header == nil) return;
    //如果头部控件正在刷新
    if (self.isHeaderRefresh) return;
    //计算偏移量
    CGFloat offsetInset = - (self.tableView.contentInset.top + self.header.XFJ_Height);
    //判断
    if (self.tableView.contentOffset.y <= offsetInset) {
        //改变文字
        self.header.text = @"松开立即刷新";
        self.header.backgroundColor = [UIColor blueColor];
    }else {
        self.header.text = @"下拉可以刷新";
        self.header.backgroundColor = [UIColor orangeColor];
    }
}
4.3 顶部刷新条开始刷新
#pragma mark - header开始刷新
- (void)headerBeginRefresh
{
    //判断如果正在刷新就直接返回
    if (self.isHeaderRefresh) return;
    //允许刷新
    self.headerRefresh = YES;
    //允许刷新的文字
    self.header.text = @"正在刷新数据...";
    //改变背景颜色
    self.header.backgroundColor = [UIColor brownColor];
    //增大内边距
    [UIView animateWithDuration:0.25 animations:^{
        UIEdgeInsets offsetIns = self.tableView.contentInset;
        offsetIns.top += self.header.XFJ_Height;
        self.tableView.contentInset = offsetIns;

        CGPoint offset = self.tableView.contentOffset;
        offset.y = - offsetIns.top;
        self.tableView.contentOffset = offset;
    }];
    //调用刷新方法
    [self setLoadNews];
}
4.4 顶部刷新条结束刷新
#pragma mark - header结束刷新
- (void)headerEndRefresh
{
    //刷新完毕后结束刷新
    self.headerRefresh = NO;
    //减小内边距
    [UIView animateWithDuration:0.25 animations:^{
        UIEdgeInsets offsetIns = self.tableView.contentInset;
        offsetIns.top -= self.header.XFJ_Height;
        self.tableView.contentInset = offsetIns;
    }];
}

九 处理细节

1 程序一启动底部的刷新条会短暂的出现在顶部位置.

—-> 解决方案: 在tableView一刷新就会调用的方法中控制.(通过模型的数量老控制)

#pragma mark - 行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    //隐藏开始启动程序的label的片刻出现
    self.refreshLabel.hidden = (self.item.count == 0);
    return self.item.count;
}

2 程序开始启动的时候,自动刷新正常,但是当手动拖拽tableView进行刷新的时候,刷新的数量并不能控制,这是不合理的.(请求数据的时候控制了服务器返回的数据量)

—-> 解决方案: 通过定义一个第三方属性来记录状态,是否停止刷新和是否开始刷新.用if来做出判断.

十 刷新功能的追加模式(查看是否有数据重复)

1 通过查看写入的plist文件,查看到在maxtime中记录了每一次返回给客户端其参数的最后一个数字.比如:刷新的时候,接收到服务器的数据是50;49;48;47的时候,客户端在刷新完后,将47返回给服务器,然后服务器会根据接收到的请求参数,将位于47后面的信息返回给客户端,这样就达到了刷新的目的同时不会重复

2 有些公司是通过page来发送,来判断返回的数据是否重叠(不推荐使用,因为会照成错漏).

十一 知识点补充

1 我们是通过插入label的方式来实现刷新的目的,同理在很多app中会出现中间某些部位有广告弹出来,我们也可以往里面插入广告.

2 补充一些有关于宏的知识:

—-> 2.1 在宏里面,两个”##”的作用:链接两个标识符
#define method(name) - (void)load##name {}
method(abc)  //- (void)loadabc {}
method(ddd)  //- (void)loadddd {}
method(ttt)  //- (void)loadttt {}
—-> 2.2 在宏里面,一个”#”的作用:给右边的标识符加上双引号.
#define test(name) @#name
test(abc) // @"abc"

十二 总结

1 该部分只是简单的tableView刷新部分,里面还有很多的不足,需要修改.作者里面表达的逻辑还是很容易明白的,只是我希望看过我这篇博客的人很有所收获,特别是要明白原理图.里面牵扯到了一些计算,不懂是没法做的.

2 最后,明天我将为大家继续完善百思不得姐app.如果大家觉得我写的博客还满意的话,麻烦大家关注我的官方博客,有什么问题,大家可以给我留言,我将一 一为大家解决,谢谢!!!!

时间: 2024-10-11 10:42:02

百思不得姐数据刷新数据部分(七)的相关文章

刷新数据

刷新数据的方法 重新载入屏幕上所有数据的方法[self.tableView reloadData]; 以某种方式插入到特定的某一行[self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:@0 inSection:@1]] withRowAnimation:UITableViewRowAnimationLeft]; 以某种方法删除某一行数据[self.tableView deleteRowsAtIndexPaths

数据刷新

*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } a { color: #4183C4; } a.absent { color: #cc0000; } a.anchor { display: block; padding-left: 30px; margin-left: -30px; cursor: pointer; position: absolute

关于初学者的一些小技巧--tableViewCell的数据刷新

就目前而言,给自定义cell赋值的时候会通过定义一个属性来储存从网络或者本地请求到的数据,具体用什么方法请求的数据,不是今天要说的重点. 今天主要分享一下对tableview上的自定义cell的数据的刷新. 应用场景,如果是用一个tableview来展示新闻概述,或者一些活动概述的时候,通常需要给cell的deselect方法管理详情页面,可以用模态也可以用push跳转下一界面,如果详情页面是可编辑的,就会牵涉到返回列表页面时的数据更新.所以在返回的时候需要做两步,一个是对对应数据库的内容进行相

iOS-UI控件之UITableView(四)- cell数据刷新

TableView- 数据刷新 数据刷新 添加数据 删除数据 更改数据 全局刷新方法(最常用) [self.tableView reloadData]; // 屏幕上的所有可视的cell都会刷新一遍 局部刷新方法 添加数据 NSArray *indexPaths = @[ [NSIndexPath indexPathForRow:0 inSection:0], [NSIndexPath indexPathForRow:1 inSection:0] ]; [self.tableView inser

iOS开发UI篇—自定义瀑布流控件(蘑菇街数据刷新操作)

iOS开发UI篇—自定义瀑布流控件(蘑菇街数据刷新操作) 一.简单说明 使用数据刷新框架: 该框架提供了两种刷新的方法,一个是使用block回调(存在循环引用问题,_ _weak),一个是使用调用. 问题:在进行下拉刷新之前,应该要清空之前的所有数据(在刷新数据这个方法中). 移除正在显示的cell: (1)把字典中的所有的值,都从屏幕上移除 (2)清除字典中的所有元素 (3)清除cell的frame,每个位置的cell的frame都要重新计算 (4)清除可复用的缓存池. 该部分的代码如下: 1

iOS TableView实现下拉刷新数据

1. 创建刷新控件, 可通过xib或代码方式创建控件: - (void)setupDownRefresh { /* 添加刷新控件 */ UIRefreshControl *control = [[UIRefreshControl alloc] init]; // 监听事件 [control addTarget:self action:@selector(loadNewDatas:) forControlEvents:UIControlEventValueChanged]; [self.table

as3+java+mysql(mybatis) 数据自动工具(七) - 完结

autoscript packed 文件地址:http://pan.baidu.com/s/1dDvgcO5 如果需要项目源码的话,可以留下邮箱,先声明一下,该工具主要是为了实现自动同步输出代码类文件的功能,所以代码写得并不是很规范什么的,没太大的参考意义,主要还是工具的实用性. 数据类和常量的配置基本就是前面所说明的那些了,现在来说一下怎么执行配置文件.执行配置文件需要写一个批处理文件,格式如下 java -classpath ./lib/*; AutoScript -? 这是一个执行 jav

解决ViewPager缓存导致不能实时刷新数据

ViewPager+Fragment,但是Fragment有个不好或者太好的地方.例如你在ViewPager中添加了三个Fragment,当加载ViewPager中第一个Fragment时,它会默认帮你预先加载了第二个Fragment,当你加载第二个Fragment时,它会帮你加载第三个Fragment. 这样用户使用的体验是不错的,但是这样可能导致每次滑动切换页面时,显示的数据都不是最新的数据.而是ViewPager预加载从内存中读取的数据. 我们怎么去解决这种问题.及时的去刷新数据. 在fr

achartengine刷新数据

achartengine工具比較强大.偶在闲余时间玩了下,想通过achartengine来模拟股票线性图,于是就针对achartengine中线性图尝试效果,achartengine中包括了非常多图表,希望同学们能够去研究下,偶仅仅会点毛片,不说那么多了,进入正题. 偶上传了应用,请到该地址下载:http://download.csdn.net/detail/a1031359915/8990855 開始解析代码: String[] titles = new String[] { "Crete&q