首页 > 代码库 > 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.实现效果:
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。