首页 > 代码库 > iOS开发项目篇—32添加上拉刷新数据

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 @end11 12 @implementation YYloadStatusesFooter13 14 +(instancetype)loadFooter15 {16     //加载xib17     return [[[NSBundle mainBundle] loadNibNamed:@"YYloadStatusesFooter" owner:nil options:nil] lastObject];18 }19 20 - (void)beginRefreshing21 {22     self.loadLabel.text = @"正在拼命加载更多数据...";23     [self.loadingView startAnimating];24     self.refreshing = YES;25 }26 27 - (void)endRefreshing28 {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)loadMoreStatuses121 {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:params136      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)count163 {164     //1.创建一个label165     UILabel *label=[[UILabel alloc]init];166     167     //2.设置label的文字168     if (count) {169         label.text=[NSString stringWithFormat:@"共有%d条新的微博数据",count];170     }else171     {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的frame181     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)setupNavBar228 {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 *)titleButton249 {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-YYPopMenuDelegate265 //弹出菜单266 -(void)popMenuDidDismissed:(YYPopMenu *)popMenu267 {268     YYTitleButton *titleButton=(YYTitleButton *)self.navigationItem.titleView;269     [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];270 }271 -(void)pop272 {273     YYLog(@"---POP---");274 }275 -(void)friendsearch276 {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 source286 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section287 {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 *)indexPath295 {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 *)indexPath313 {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 *)scrollView323 {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.如果能看见整个footer332     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.实现效果: