iOS开发项目篇—32添加上拉刷新数据

iOS开发项目篇—32添加上拉刷新数据

一、简单说明

图片示意

思路:可以自定义一个view(示意xib),在view中添加一个label和菊花,指示状态。把这个view设置为tableView的底部视图。

二、实现过程

1.新建一个类和xib,关联

(1)创建一个类,让其继承自UIView

(2)创建一个xib文件,用来定义上拉提示框

(3)定义的xib文件,把类和xib文件进行关联

2.实现代码:

YYlaodStatusesFooter.h文件

 1 //
 2 //  YYlaodStatusesFooter.h
 3 //
 4
 5 #import <UIKit/UIKit.h>
 6
 7 @interface YYloadStatusesFooter : UIView
 8 +(instancetype)loadFooter;
 9
10
11 - (void)beginRefreshing;
12 - (void)endRefreshing;
13
14 @property (nonatomic, assign, getter = isRefreshing) BOOL refreshing;
15 @end

YYlaodStatusesFooter.m文件

 1 //
 2 //  YYlaodStatusesFooter.m
 3 //
 4
 5 #import "YYloadStatusesFooter.h"
 6
 7 @interface YYloadStatusesFooter ()
 8 @property (weak, nonatomic) IBOutlet UILabel *loadLabel;
 9 @property (weak, nonatomic) IBOutlet UIActivityIndicatorView *loadingView;
10 @end
11
12 @implementation YYloadStatusesFooter
13
14 +(instancetype)loadFooter
15 {
16     //加载xib
17     return [[[NSBundle mainBundle] loadNibNamed:@"YYloadStatusesFooter" owner:nil options:nil] lastObject];
18 }
19
20 - (void)beginRefreshing
21 {
22     self.loadLabel.text = @"正在拼命加载更多数据...";
23     [self.loadingView startAnimating];
24     self.refreshing = YES;
25 }
26
27 - (void)endRefreshing
28 {
29     self.loadLabel.text = @"上拉可以加载更多数据";
30     [self.loadingView stopAnimating];
31     self.refreshing = NO;
32 }
33 @end

YYHomeTableViewController.m文件

  1 //
  2 //  YYHomeTableViewController.m
  3 //
  4
  5 #import "YYHomeTableViewController.h"
  6 #import "YYOneViewController.h"
  7 #import "YYTitleButton.h"
  8 #import "YYPopMenu.h"
  9 #import "YYAccountModel.h"
 10 #import "YYAccountTool.h"
 11 #import "AFNetworking.h"
 12 #import "UIImageView+WebCache.h"
 13 #import "YYUserModel.h"
 14 #import "YYStatusModel.h"
 15 #import "MJExtension.h"
 16 #import "YYloadStatusesFooter.h"
 17
 18 @interface YYHomeTableViewController ()<YYPopMenuDelegate>
 19 @property(nonatomic,assign)BOOL down;
 20 @property(nonatomic,strong)NSMutableArray *statuses;
 21 @property(nonatomic,strong)YYloadStatusesFooter *footer;
 22 @end
 23
 24 @implementation YYHomeTableViewController
 25
 26 #pragma mark- 懒加载
 27 -(NSMutableArray *)statuses
 28 {
 29     if (_statuses==nil) {
 30         _statuses=[NSMutableArray array];
 31     }
 32     return _statuses;
 33 }
 34 - (void)viewDidLoad
 35 {
 36     [super viewDidLoad];
 37
 38     //设置导航栏内容
 39     [self setupNavBar];
 40
 41     //集成刷新控件
 42     [self setupRefresh];
 43 }
 44
 45 //集成刷新控件
 46 -(void)setupRefresh
 47 {
 48     // 1.添加下拉刷新控件
 49     UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
 50     [self.tableView addSubview:refreshControl];
 51
 52     //2.监听状态
 53     [refreshControl addTarget:self action:(@selector(refreshControlStateChange:)) forControlEvents:UIControlEventValueChanged];
 54
 55     //3.让刷新控件自动进入到刷新状态
 56     [refreshControl beginRefreshing];
 57
 58     //4.手动调用方法,加载数据
 59     //模拟网络延迟,延迟2.0秒
 60     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
 61         [self refreshControlStateChange:refreshControl];
 62     });
 63
 64     //5.上拉刷新数据
 65     YYloadStatusesFooter *footer=[YYloadStatusesFooter loadFooter];
 66     self.tableView.tableFooterView=footer;
 67     self.footer=footer;
 68
 69
 70 }
 71
 72 /**
 73  *  当下拉刷新控件进入刷新状态(转圈圈)的时候会自动调用
 74  */
 75 -(void)refreshControlStateChange:(UIRefreshControl *)refreshControl
 76 {
 77     //1.获得请求管理者
 78     AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
 79
 80     //2.封装请求参数
 81     NSMutableDictionary *params=[NSMutableDictionary dictionary];
 82     params[@"access_token"] =[YYAccountTool accountModel].access_token;
 83     //取出当前微博模型中的第一条数据,获取第一条数据的id
 84     YYStatusModel *firstStatus=[self.statuses firstObject];
 85     if (firstStatus) {
 86         params[@"since_id"]=firstStatus.idstr;
 87     }
 88
 89     //3.发送Get请求
 90     [mgr GET:@"https://api.weibo.com/2/statuses/home_timeline.json" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary*accountDict) {
 91         // 微博字典 -- 数组
 92         NSArray *statusDictArray = accountDict[@"statuses"];
 93         //微博字典数组---》微博模型数组
 94        NSArray *newStatuses =[YYStatusModel objectArrayWithKeyValuesArray:statusDictArray];
 95
 96         //把新数据添加到旧数据的前面
 97         NSRange range=NSMakeRange(0, newStatuses.count);
 98         NSIndexSet *indexSet=[NSIndexSet indexSetWithIndexesInRange:range];
 99         [self.statuses insertObjects:newStatuses atIndexes:indexSet];
100         YYLog(@"刷新了--%d条新数据",newStatuses.count);
101
102         //重新刷新表格
103         [self.tableView reloadData];
104         //让刷新控件停止刷新(回复默认的状态)
105         [refreshControl endRefreshing];
106
107         [self showNewStatusesCount:newStatuses.count];
108
109     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
110         YYLog(@"请求失败");
111         //让刷新控件停止刷新(回复默认的状态)
112         [refreshControl endRefreshing];
113     }];
114
115 }
116
117 /**
118  *  加载更多的微博数据
119  */
120 - (void)loadMoreStatuses
121 {
122     // 1.获得请求管理者
123     AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
124
125     // 2.封装请求参数
126     NSMutableDictionary *params = [NSMutableDictionary dictionary];
127     params[@"access_token"] = [YYAccountTool accountModel].access_token;
128     YYStatusModel *lastStatus =  [self.statuses lastObject];
129     if (lastStatus) {
130         // max_id    false    int64    若指定此参数,则返回ID小于或等于max_id的微博,默认为0。
131         params[@"max_id"] = @([lastStatus.idstr longLongValue] - 1);
132     }
133
134     // 3.发送GET请求
135     [mgr GET:@"https://api.weibo.com/2/statuses/home_timeline.json" parameters:params
136      success:^(AFHTTPRequestOperation *operation, NSDictionary *resultDict) {
137          // 微博字典数组
138          NSArray *statusDictArray = resultDict[@"statuses"];
139          // 微博字典数组 ---> 微博模型数组
140          NSArray *newStatuses = [YYStatusModel objectArrayWithKeyValuesArray:statusDictArray];
141
142          // 将新数据插入到旧数据的最后面
143          [self.statuses addObjectsFromArray:newStatuses];
144
145          // 重新刷新表格
146          [self.tableView reloadData];
147
148          // 让刷新控件停止刷新(恢复默认的状态)
149          [self.footer endRefreshing];
150      } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
151          YYLog(@"请求失败--%@", error);
152          // 让刷新控件停止刷新(恢复默认的状态)
153          [self.footer endRefreshing];
154      }];
155 }
156
157 /**
158  *  提示用户最新的微博数量
159  *
160  *  @param count 最新的微博数量
161  */
162 -(void)showNewStatusesCount:(int)count
163 {
164     //1.创建一个label
165     UILabel *label=[[UILabel alloc]init];
166
167     //2.设置label的文字
168     if (count) {
169         label.text=[NSString stringWithFormat:@"共有%d条新的微博数据",count];
170     }else
171     {
172         label.text=@"没有最新的微博数据";
173     }
174
175     //3.设置label的背景和对其等属性
176     label.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageWithName:@"timeline_new_status_background"]];
177     label.textAlignment=UITextAlignmentCenter;
178     label.textColor=[UIColor whiteColor];
179
180     //4.设置label的frame
181     label.x=0;
182     label.width=self.view.width;
183     label.height=35;
184 //    label.y=64-label.height;
185    label.y=self.navigationController.navigationBar.height+20-label.height;
186
187     //5.把lable添加到导航控制器的View上
188 //    [self.navigationController.view addSubview:label];
189     //把label添加到导航控制器上,显示在导航栏的下面
190     [self.navigationController.view insertSubview:label belowSubview:self.navigationController.navigationBar];
191
192     //6.设置动画效果
193     CGFloat duration=0.75;
194     //设置提示条的透明度
195     label.alpha=0.0;
196    [UIView animateWithDuration:duration animations:^{
197        //往下移动一个label的高度
198        label.transform=CGAffineTransformMakeTranslation(0, label.height);
199        label.alpha=1.0;
200    } completion:^(BOOL finished) {//向下移动完毕
201
202        //延迟delay秒的时间后,在执行动画
203        CGFloat delay=0.5;
204
205        [UIView animateKeyframesWithDuration:duration delay:delay options:UIViewAnimationOptionCurveEaseOut animations:^{
206
207            //恢复到原来的位置
208            label.transform=CGAffineTransformIdentity;
209            label.alpha=0.0;
210
211        } completion:^(BOOL finished) {
212
213            //删除控件
214            [label removeFromSuperview];
215        }];
216    }];
217 }
218
219 /**
220  UIViewAnimationOptionCurveEaseInOut            = 0 << 16, // 开始:由慢到快,结束:由快到慢
221  UIViewAnimationOptionCurveEaseIn               = 1 << 16, // 由慢到块
222  UIViewAnimationOptionCurveEaseOut              = 2 << 16, // 由快到慢
223  UIViewAnimationOptionCurveLinear               = 3 << 16, // 线性,匀速
224  */
225
226 /**设置导航栏内容*/
227 -(void)setupNavBar
228 {
229     self.navigationItem.leftBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_friendsearch" highImageName:@"navigationbar_friendsearch_highlighted" target:self action:@selector(friendsearch)];
230     self.navigationItem.rightBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_pop" highImageName:@"navigationbar_pop_highlighted" target:self action:@selector(pop)];
231
232     //设置导航栏按钮
233     YYTitleButton *titleButton=[[YYTitleButton alloc]init];
234     //设置文字
235     [titleButton setTitle:@"首页" forState:UIControlStateNormal];
236     //设置图标
237     [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
238     //设置背景
239     [titleButton setBackgroundImage:[UIImage resizedImage:@"navigationbar_filter_background_highlighted"] forState:UIControlStateHighlighted];
240
241     //设置尺寸
242     titleButton.width=100;
243     titleButton.height=35;
244     //监听按钮的点击事件
245     [titleButton addTarget:self action:@selector(titleButtonClick:) forControlEvents:UIControlEventTouchUpInside];
246     self.navigationItem.titleView=titleButton;
247 }
248 -(void)titleButtonClick:(UIButton *)titleButton
249 {
250
251         [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
252
253         UITableView *tableView=[[UITableView alloc]init];
254         [tableView setBackgroundColor:[UIColor yellowColor]];
255         YYPopMenu *menu=[YYPopMenu popMenuWithContentView:tableView];
256         [menu showInRect:CGRectMake(60, 55, 200, 200)];
257         menu.dimBackground=YES;
258
259     menu.arrowPosition=YYPopMenuArrowPositionRight;
260         menu.delegate=self;
261 }
262
263
264 #pragma mark-YYPopMenuDelegate
265 //弹出菜单
266 -(void)popMenuDidDismissed:(YYPopMenu *)popMenu
267 {
268     YYTitleButton *titleButton=(YYTitleButton *)self.navigationItem.titleView;
269     [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
270 }
271 -(void)pop
272 {
273     YYLog(@"---POP---");
274 }
275 -(void)friendsearch
276 {
277     //跳转到one这个子控制器界面
278     YYOneViewController *one=[[YYOneViewController alloc]init];
279     one.title=@"One";
280     //拿到当前控制器
281     [self.navigationController pushViewController:one animated:YES];
282
283 }
284
285 #pragma mark - Table view data source
286 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
287 {
288 #warning 监听tableView每次显示数据的过程
289     //在tableView显示之前,判断有没有数据,如有有数据那么就显示底部视图
290     self.footer.hidden=self.statuses.count==0;
291     return self.statuses.count;
292 }
293
294 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
295 {
296     static NSString *ID = @"cell";
297     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
298     if (!cell) {
299         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
300     }
301
302       //取出这行对应的微博字典数据,转换为数据模型
303     YYStatusModel *status=self.statuses[indexPath.row];
304     cell.textLabel.text=status.text;
305     cell.detailTextLabel.text=status.user.name;
306     NSString *imageUrlStr=status.user.profile_image_url;
307     [cell.imageView setImageWithURL:[NSURL URLWithString:imageUrlStr] placeholderImage:[UIImage imageWithName:@"avatar_default_small"]];
308
309     return cell;
310 }
311
312 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
313 {
314     //点击cell的时候,跳到下一个界面
315     UIViewController *newVc = [[UIViewController alloc] init];
316     newVc.view.backgroundColor = [UIColor redColor];
317     newVc.title = @"新控制器";
318     [self.navigationController pushViewController:newVc animated:YES];
319 }
320
321 #pragma mark-代理方法
322 - (void)scrollViewDidScroll:(UIScrollView *)scrollView
323 {
324     if (self.statuses.count <= 0 || self.footer.isRefreshing) return;
325
326     // 1.差距
327     CGFloat delta = scrollView.contentSize.height - scrollView.contentOffset.y;
328     // 刚好能完整看到footer的高度
329     CGFloat sawFooterH = self.view.height - self.tabBarController.tabBar.height;
330
331     // 2.如果能看见整个footer
332     if (delta <= (sawFooterH - 0)) {
333         // 进入上拉刷新状态
334         [self.footer beginRefreshing];
335
336         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
337             // 加载更多的微博数据
338             [self loadMoreStatuses];
339         });
340     }
341 }
342 @end

3.实现效果:

  

iOS开发项目篇—32添加上拉刷新数据

时间: 2024-10-27 06:42:27

iOS开发项目篇—32添加上拉刷新数据的相关文章

iOS开发项目篇—04添加导航栏的按钮

iOS开发项目篇—04添加导航栏的按钮 一.设置导航栏的按钮 要求实现的效果:             说明:默认状态下和高亮状态下的图片是不一样的. 按钮的图片需要设置默认状态和高亮状态时的显示,系统了提供的下面方法 viewController.navigationItem.leftBarButtonItem=[UIBarButtonItem alloc]initWithImage:<#(UIImage *)#> style:<#(UIBarButtonItemStyle)#>

iOS开发项目篇—02添加子控制器以及项目分层

iOS开发项目篇—02添加子控制器以及项目分层 一.添加子控制器 1.设置根控制器(自定义) 说明:分析新浪微博应用,观察其整体建构层次.而系统的控制器不能满足项目开发的需求,这里把项目中原有的控制器删除. 自己定义一个TabBarViewController类.让这个类作为window窗口的根控制器. YYAppDelegate.m文件代码: 1 #import "YYAppDelegate.h" 2 #import "YYTabBarViewController.h&qu

iOS开发项目篇—03添加导航控制器

iOS开发项目篇—03添加导航控制器 一.简单说明 分析:分析微博应用,我们需要给每个子控制器都添加一个导航控制器(每个子控制器的导航不一样),所以需要新建一个导航控制器,然后把该导航控制器作为window的根控制器,添加的四个子控制器,分别添加在导航控制器上,也就是说整个项目采用当前主流的UI框架,一个UITabBarController管理着四个UINavigationController,而每个UINavigationController则分别管理着“首页”.“消息”.“发现”和“我”这四

iOS开发项目篇—30下拉刷新

iOS开发项目篇—30下拉刷新 一.网络监控 当应用所处的网络环境不好的时候,获取不到相应的网络数据,考虑到用户对应用的使用体验,有必要对网络的状况进行监听. 在程序启动完的时候,监控网络 YYAppDelegate.m文件代码: 1 // 2 // YYAppDelegate.m 3 // 4 5 #import "YYAppDelegate.h" 6 #import "YYOAuthViewController.h" 7 #import "YYCont

iOS开发项目篇—36封装微博业务

iOS开发项目篇—36封装微博业务 一.简单说明 1.请求参数面向模型 2.请求结果面向模型 3.对控制器来说应该屏蔽业务细节.不让控制器关心(知道)业务细节,它只需要知道自己在做某个业务 @通过一个专门的业务处理类:处理微博业务细节 说明: 业务:加载新的微博首页数据 实现:给新浪服务器发送一个GET请求 业务:加载更多的首页微博数据 实现1:给新浪服务器发送一个GET请求 实现2:去沙盒中加载以前离线缓存的微博数据  二.实现 1.新建一个微博业务处理类,继承自NSObject 微博业务处理

iOS开发项目篇—34获取用户信息

iOS开发项目篇—34获取用户信息 一.简单说明 需求:获取当前用户的昵称 ,需要获取当前登录用户的个人信息. 查看接口 要求传递的参数 这里要获取的时用户的昵称(所以使用用户id作为参数传入) 二.实现代码 1 - (void)viewDidLoad 2 { 3 [super viewDidLoad]; 4 5 //设置导航栏内容 6 [self setupNavBar]; 7 8 //集成刷新控件 9 [self setupRefresh]; 10 11 //设置用户的昵称为标题 12 [s

iOS开发项目篇—39获取用户未读的微博信息(信息提醒)

iOS开发项目篇—39获取用户未读的微博信息(信息提醒) 一.简单说明 1.实现效果       2.实现 (1)新建一个类,封装请求 查看新浪官方要求的请求参数 该类中的代码设计 YYUnreadCountParam.h文件 1 // YYUnreadCountParam.h 2 //封装请求参数的类 3 4 #import "YYBaseParam.h" 5 6 @interface YYUnreadCountParam : YYBaseParam 7 /**uid true in

iOS开发项目篇—41cell的frame的细节处理

iOS开发项目篇—41cell的frame的细节处理 一.简单说明 在首页控制器中使用自定义的UITableViewcell 代码如下: YYHomeTableViewController.m文件 1 // 2 // YYHomeTableViewController.m 3 // 4 5 #import "YYHomeTableViewController.h" 6 #import "YYOneViewController.h" 7 #import "Y

iOS开发项目篇—35封装网络请求

iOS开发项目篇—35封装网络请求 一.简单说明 1.分析项目对网路请求(AFN框架)的依赖 项目中,多个控制器都使用了AFN框架发送网络请求,如果AFN2.0存在重大BUg,或者是升级至3.0版本,那么对于整个项目都是及其危险的,所有用到AFN的地方都需要做出相应的修改. 另外,如果现在要求不再使用AFN框架,而是使用一个新的框架,那么有关AFN的依赖所关联的所有代码都需要重新来过. 如果把afn这个第三方框架从项目中删除的话,那么项目就相当于作废了,这就是项目对第三方框架的强依赖的体现. 说