A.下拉刷新微博
1.需求
  • 在“首页”界面,下拉到一定距离的时候刷新微博数据
  • 刷新数据的时候使用控件提示
  • 新数据要加在旧数据的前面
  • 刷新完毕隐藏刷新控件
  • 刷新数据完毕,导航栏下方弹出一个提示框,提示刷新微博数量
 
2.思路
  • 直接使用系统自带的UIRefreshControl就可以做出动画效果
  • 使用微博的获取微博API参数since_id可以控制加载的微博从哪个id开始
  • 使用可变数组来拼接新旧微博数据
  • 创建一个UILabel放在导航控制器view上来提示刷新数据(放在TableView上会被滚走)
 
3.实现
(1)每条微博都有一个id,这个id是随时间递进叠加的,id越大越新
 
(2)获取微博API参数
 
(3)在“首页”控制器加上下拉刷新代码
以前的加载微博数据方法"loadWeiboData",也用刷新方法代替
 //  HVWHomeViewController.m
- (void)viewDidLoad {
[super viewDidLoad]; self.tableView.delegate = self; // 设置导航栏
[self setupNavigationBar]; // 添加刷新器
[self addRefresh];
} /** 初始化status */
- (NSMutableArray *)statuses {
if (nil == _statuses) {
_statuses = [NSMutableArray array];
}
return _statuses;
} /** 添加刷新器 */
- (void) addRefresh {
// 下拉刷新最新微博
// 添加刷新控件
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
self.refreshControl = refreshControl;
[self.view addSubview:refreshControl]; // 刷新控件下拉事件
[refreshControl addTarget:self action:@selector(refreshLatestWeibo:) forControlEvents:UIControlEventValueChanged]; // 开启的时候自动进入刷新状态
[refreshControl beginRefreshing];
// 加载微博数据
[self refreshLatestWeibo:refreshControl];
} /** 刷新最新微博数据 */
- (void) refreshLatestWeibo:(UIRefreshControl *) refreshControl {
// 把最新的微博数据加到原来的微博前面 // 创建AFNetworking的http操作中管理器
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; // 设置参数
NSMutableDictionary *param = [NSMutableDictionary dictionary];
param[@"access_token"] = [HVWAccountInfoTool accountInfo].access_token; /** 若指定此参数,则返回ID比since_id大的微博(即比since_id时间晚的微博),默认为0。*/
HVWStatus *firstStatus = [self.statuses firstObject];
if (firstStatus) {
param[@"since_id"] = firstStatus.idstr;
} // 发送请求
[manager GET:@"https://api.weibo.com/2/statuses/home_timeline.json" parameters:param success:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) {
// HVWLog(@"获取微博数据成功-------%@", responseObject); // 保存数据到内存
NSArray *dataArray = responseObject[@"statuses"]; // 得到新微博数据
// 使用MJExtension直接进行字典-模型转换
NSArray *newStatus = [HVWStatus objectArrayWithKeyValuesArray:dataArray]; // 插入到微博数据数组的最前面
NSRange newWeiboRange = NSMakeRange(, newStatus.count);
NSIndexSet *newWeiboIndexSet = [NSIndexSet indexSetWithIndexesInRange:newWeiboRange];
[self.statuses insertObjects:newStatus atIndexes:newWeiboIndexSet]; // 刷新数据
[self.tableView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
HVWLog(@"获取微博数据失败------%@", error);
}]; // 缩回刷新器
[refreshControl endRefreshing];
}
 
 
(4)添加一个UILabel提示更新微博数量,在请求微博数据成功后显示
 /** 弹出微博更新提示框 */
- (void) showRefreshIndicator:(int) refreshCount {
// 创建UILabel
UILabel *refreshIndicatorLabel = [[UILabel alloc] init];
refreshIndicatorLabel.textAlignment = NSTextAlignmentCenter; // 设置文本
refreshIndicatorLabel.text = [NSString stringWithFormat:@"更新了%d条微博", refreshCount]; // 设置背景
refreshIndicatorLabel.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithNamed:@"timeline_new_status_background"]]; // 设置位置尺寸
refreshIndicatorLabel.width = self.navigationController.view.width;
refreshIndicatorLabel.height = ;
refreshIndicatorLabel.x = ;
// 因为一开始是藏在导航栏上的,所以要减去自身的高度
refreshIndicatorLabel.y = [UIApplication sharedApplication].statusBarFrame.size.height + self.navigationController.navigationBar.height - refreshIndicatorLabel.height; // 添加到导航控制器view,要加载导航器的下面
[self.navigationController.view insertSubview:refreshIndicatorLabel belowSubview:self.navigationController.navigationBar]; // 使用动画弹出
[UIView animateWithDuration:1.0 animations:^{
// 使用更改transform来实现
refreshIndicatorLabel.transform = CGAffineTransformMakeTranslation(, refreshIndicatorLabel.height);
} completion:^(BOOL finished) {
// 弹出完毕后,再使用动画缩回
[UIView animateWithDuration:1.0 delay:1.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
// 恢复位置
refreshIndicatorLabel.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
// 从导航view删除
[refreshIndicatorLabel removeFromSuperview];
}];
}];
}
 
 
 
B.上拉加载旧微博数据
1.需求
当浏览到了缓存的所有微博数据底部的时候,上拉加载更多的旧微博数据
也具有一个加载提示器
 
2.思路
跟下拉加载新微博一样,使用获取微博API中的“max_id”参数
如果需要加载等待动画图标(菊花图标),可以使用代码或xib创建一个UIView
加载在tableView的footerView上
 
 
3.实现
(1)设计一个“加载更多”控件
 //
// HVWLoadMoreWeiboFooterView.m
// HVWWeibo
//
// Created by hellovoidworld on 15/2/6.
// Copyright (c) 2015年 hellovoidworld. All rights reserved.
// #import "HVWLoadMoreWeiboFooterView.h" @interface HVWLoadMoreWeiboFooterView() /** 加载更多微博文本 */
@property(nonatomic, strong) UILabel *label; /** 加载中活动指示器 */
@property(nonatomic, strong) UIActivityIndicatorView *actIndicator; @end @implementation HVWLoadMoreWeiboFooterView - (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame]; self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithNamed:@"timeline_new_status_background"]]; // 设置加载文本
UILabel *label = [[UILabel alloc] init];
label.textAlignment = NSTextAlignmentCenter;
label.text = @"上拉加载更多微博";
self.label = label;
[self addSubview:label]; // 设置加载活动指示器
// 不同类型的活动指示器大小是不一样的,要注意
UIActivityIndicatorView *actIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
self.actIndicator = actIndicator;
[self addSubview:actIndicator]; return self;
} /** 设置位置尺寸 */
- (void)layoutSubviews {
[super layoutSubviews]; // 设置本身frame
self.width = [UIScreen mainScreen].bounds.size.width;
self.height = ; // 设置文本frame
self.label.frame = self.bounds; // 设置活动指示器frame
CGFloat marginX = ;
self.actIndicator.x = self.width - self.actIndicator.width - marginX;
self.actIndicator.y = (self.height - self.actIndicator.height) * 0.5;
} @end
 
加在tableView的footerView上,没有微博数据的时候不需要显示(app启动的时候)
 //  HVWHomeViewController.m
/** 添加刷新器 */
- (void) addRefresh {
// 下拉刷新最新微博
// 添加刷新控件
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
self.refreshControl = refreshControl;
[self.view addSubview:refreshControl]; // 刷新控件下拉事件
[refreshControl addTarget:self action:@selector(refreshLatestWeibo:) forControlEvents:UIControlEventValueChanged]; // 开启的时候自动进入刷新状态
[refreshControl beginRefreshing];
// 加载微博数据
[self refreshLatestWeibo:refreshControl]; // 添加上拉刷新器
HVWLoadMoreWeiboFooterView *loadMoreFooter = [[HVWLoadMoreWeiboFooterView alloc] init];
self.loadMoreFooter = loadMoreFooter;
self.tableView.tableFooterView = loadMoreFooter; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// 没有微博数据的时候,不需要显示“加载更多微博”控件
self.loadMoreFooter.hidden = self.statuses.count==?YES:NO; return self.statuses.count;
}
 
 
 
(2)上拉刷新动作监听
a.给“上拉刷新”控件增加状态管理属性和方法
 //
// HVWLoadMoreWeiboFooterView.h
// HVWWeibo
//
// Created by hellovoidworld on 15/2/6.
// Copyright (c) 2015年 hellovoidworld. All rights reserved.
// #import <UIKit/UIKit.h> @interface HVWLoadMoreWeiboFooterView : UIView /** 是否正在刷新 */
@property(nonatomic, assign, getter=isRefreshing) BOOL refreshing; /** 开始刷新 */
- (void) beginRefresh;
/** 停止刷新 */
- (void) endRefresh; @end //
// HVWLoadMoreWeiboFooterView.m
// HVWWeibo
//
// Created by hellovoidworld on 15/2/6.
// Copyright (c) 2015年 hellovoidworld. All rights reserved.
// #import "HVWLoadMoreWeiboFooterView.h" @interface HVWLoadMoreWeiboFooterView() /** 加载更多微博文本 */
@property(nonatomic, strong) UILabel *label; /** 加载中活动指示器 */
@property(nonatomic, strong) UIActivityIndicatorView *actIndicator; @end @implementation HVWLoadMoreWeiboFooterView - (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame]; self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithNamed:@"timeline_new_status_background"]]; // 设置加载文本
UILabel *label = [[UILabel alloc] init];
label.textAlignment = NSTextAlignmentCenter;
label.text = @"上拉加载更多微博";
self.label = label;
[self addSubview:label]; // 设置加载活动指示器
// 不同类型的活动指示器大小是不一样的,要注意
UIActivityIndicatorView *actIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
self.actIndicator = actIndicator;
[self addSubview:actIndicator]; return self;
} /** 设置位置尺寸 */
- (void)layoutSubviews {
[super layoutSubviews]; // 设置本身frame
self.width = [UIScreen mainScreen].bounds.size.width;
self.height = ; // 设置文本frame
self.label.frame = self.bounds; // 设置活动指示器frame
CGFloat marginX = ;
self.actIndicator.x = self.width - self.actIndicator.width - marginX;
self.actIndicator.y = (self.height - self.actIndicator.height) * 0.5;
} /** 开始刷新 */
- (void) beginRefresh {
self.label.text = @"正在努力加载更多微博...";
[self.actIndicator startAnimating];
self.refreshing = YES;
} /** 停止刷新 */
- (void) endRefresh {
self.label.text = @"上拉加载更多微博";
[self.actIndicator stopAnimating];
self.refreshing = NO;
} @end
 
b.在“首页”控制器中,监听滚动操作,当“上拉刷新”控件完全露出的时候启动刷新
 //  HVWHomeViewController.m
/** 加载更多(旧)微博 */
- (void) loadMoreWeiboData {
// 把更多的微博数据加到原来的微博后面 // 创建AFNetworking的http操作中管理器
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; // 设置参数
NSMutableDictionary *param = [NSMutableDictionary dictionary];
param[@"access_token"] = [HVWAccountInfoTool accountInfo].access_token; /** 若指定此参数,则返回ID小于或等于max_id的微博,默认为0。*/
HVWStatus *lastStatus = [self.statuses lastObject];
if (lastStatus) {
param[@"max_id"] = @([lastStatus.idstr longLongValue] - );
} // 发送请求
[manager GET:@"https://api.weibo.com/2/statuses/home_timeline.json" parameters:param success:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) {
// HVWLog(@"获取微博数据成功-------%@", responseObject); // 保存数据到内存
NSArray *dataArray = responseObject[@"statuses"]; // 得到新微博数据
// 使用MJExtension直接进行字典-模型转换
NSArray *newStatus = [HVWStatus objectArrayWithKeyValuesArray:dataArray]; // 插入到微博数据数组的后面
[self.statuses addObjectsFromArray:newStatus]; // 刷新数据
[self.tableView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
HVWLog(@"获取微博数据失败------%@", error);
}]; [self.loadMoreFooter endRefresh];
} #pragma mark - UIScrollViewDelegate
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
// 如果正在加载中,不用重复加载
if (self.loadMoreFooter.isRefreshing) return; // 滚动时,scrollView处于屏幕顶部下方的内容长度
CGFloat scrollingDelta = scrollView.contentSize.height - scrollView.contentOffset.y;
// 当scrollView向上滚栋到刚好露出“上拉刷新”控件时,scrollView处于屏幕下方的内容长度
CGFloat scrollViewHeighWithFooter = self.tableView.height - self.tabBarController.tabBar.height - self.loadMoreFooter.height; // 当向上滚动至scrollView能够显示的内容少于刚好露出“上拉刷新”控件时显示的内容,证明“上拉刷新”控件已经完全露出,可以刷新
if (scrollingDelta < scrollViewHeighWithFooter) {
[self.loadMoreFooter beginRefresh];
[self loadMoreWeiboData];
}
}
 
 
 
 

[iOS微博项目 - 3.0] - 手动刷新微博的更多相关文章

  1. [iOS微博项目 - 2.0] - OAuth授权3步

    A.概念      OAUTH协议为用户资源的授权提供了一个安全的.开放而又简易的标准.与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用 ...

  2. [iOS微博项目 - 4.0] - 自定义微博cell

    github: https://github.com/hellovoidworld/HVWWeibo A.自定义微博cell基本结构 1.需求 创建自定义cell的雏形 cell包含:内容.工具条 内 ...

  3. [iOS微博项目 - 1.0] - 搭建基本框架

    A.搭建基本环境   github: https://github.com/hellovoidworld/HVWWeibo   项目结构:   1.使用代码构建UI,不使用storyboard     ...

  4. [iOS微博项目 - 4.5] - 每条微博的底部工具条

    github: https://github.com/hellovoidworld/HVWWeibo A.每条微博的底部工具条 1.需求 每条微博底部都有一个工具条 显示3个按钮:评论.转发.赞 按钮 ...

  5. [iOS微博项目 - 4.2] - 设置转发微博背景

    github: https://github.com/hellovoidworld/HVWWeibo A.转发微博部分的淡灰色背景 1.需求 转发微博部分需要设置背景色 使用图片作为背景   2.思路 ...

  6. iOS开发小技巧--微博项目中的键盘工具条

    微博项目中的键盘工具条 项目中的键盘工具条不能使用inputAccessoryView,因为inputAccessoryView不能实现键盘隐藏的时候,工具条还显示在眼前,如图: 所以,果断决定将工具 ...

  7. [iOS微博项目 - 2.6] - 获取微博数据

    github: https://github.com/hellovoidworld/HVWWeibo   A.新浪获取微博API 1.读取微博API     2.“statuses/home_time ...

  8. [iOS微博项目 - 3.6] - 获取未读消息

    github: https://github.com/hellovoidworld/HVWWeibo   A.获取登陆用户未读消息 1.需求 获取所有未读消息,包括新微博.私信.@.转发.关注等 把未 ...

  9. AJ学IOS 之微博项目实战(8)用AFNetworking和SDWebImage简单加载微博数据

    AJ分享,必须精品 一:效果 没有图文混排,也没有复杂的UI,仅仅是简单的显示出微博数据,主要介绍AFNetworking和SDWebImage的简单用法 二:加载数据AFNetworking AFN ...

随机推荐

  1. HDU 1525 (博弈) Euclid's Game

    感觉这道题用PN大法好像不顶用了,可耻地看了题解. 考虑一下简单的必胜状态,某一个数是另一个数的倍数的时候是必胜状态. 从这个角度考虑一下:游戏进行了奇数步还是偶数步决定了哪一方赢. 如果b > ...

  2. 使用MFC中的AfxBeginThread创建多线程

    创建一个基于对话框的工程,工程名为CreateThreadRect   在CreateThreadRect.cpp中增加一个ThreadProc函数,代码如下   工作者线程的函数必须是全局函数或静态 ...

  3. BZOJ 1078 斜堆

    感谢MATO大神的博客 http://www.cppblog.com/MatoNo1/archive/2013/03/03/192131.html 注意细节. #include<iostream ...

  4. VIM Ctrl-V Conflict with Windows Paste

    /************************************************************************************** * VIM Ctrl-V ...

  5. dede调用第一张大图,非缩略图

    1.找到include/extend.func.php加入现在函数 function firstimg($str_pic) { $str_sub=substr($str_pic,0,-7)." ...

  6. (六) 语言模型 Language Madel 与 word2vec

    语言模型简介(Language Model) 简单的说,语言模型 (Language Model) 是用来计算一个句子出现概率的模型,假设句子  ,其中  代表句子中的第  个词语,则语句 W 以该顺 ...

  7. SQLServer如何快速生成100万条不重复的随机8位数字

    最近在论坛看到有人问,如何快速生成100万不重复的8位编号,对于这个问题,有几点是需要注意的: 1.    如何生成8位随机数,生成的数越随机,重复的可能性当然越小 2.    控制不重复 3.    ...

  8. JVM内存结构之三--持久代

    本文会介绍一些JVM内存结构的基本概念,然后很快会讲到持久代,来看下Java SE 8发布后它究竟到哪去了. 基础知识 JVM只不过是运行在你系统上的另一个进程而已,这一切的魔法始于一个java命令. ...

  9. (转载)OC学习篇之---协议的概念和用法

    在前一篇文章中我们介绍了OC中类的延展,这一篇文章我们在来看一下OC中协议的概念以及用法,协议也是OC中的一个重点,Foundation框架以及我们后面在写代码都会用到. OC中的协议就是相当于Jav ...

  10. Oracle 游标使用(转)

    这个文档几乎包含了oracle游标使用的方方面面,全部通过了测试 ; ; dbms_output.put_line(sql) loop dbms_output.put_line( ; ; ; r_te ...