程序员人生 网站导航

不借助第三方插件利用ScrollView自身delegate实现下拉刷新和上拉加载

栏目:综合技术时间:2015-06-01 08:46:05

下拉刷新功能基本上在所有的app中都会被用到,而且这个功能已被apple集成进去了,不过必须得是在tableViewController中才有,是1个叫做UIRefreshControl的控件,想看效果可以看手机QQ上面联系人列表下拉后的刷新。这里不多介绍。

本篇blog主要介绍如何在scrollview中实现下拉刷新的效果。由于有些时候我们可能更多地希望直接在scrollview中展现,而不是1定要局限于tableviewcontroller。

固然网上有很多下拉刷新和上拉加载的第3方控件,但是我这个人还是喜欢用系统原生API自己来做,1方面更能把原理吃透,另外一方面方便自己定义。

好了,空话不多说了,直接上代码:


准备工作:

// 设置下拉刷新的process和label self.indicatorView = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(self.frame.size.width/2 - 50, ⑵5, 20, 20)]; [self.indicatorView setColor:[UIColor blackColor]]; self.pullRefreshLabel = [[UILabel alloc]initWithFrame:CGRectMake(self.frame.size.width/2 ⑵0, ⑶0, 90, 30)]; self.pullRefreshLabel.font = [UIFont fontWithName:@"heiti SC" size:14]; [self.pullRefreshLabel setText:@"下拉刷新"]; [self.scroll_view addSubview:self.indicatorView]; [self.scroll_view addSubview:self.pullRefreshLabel]; [self.scroll_view bringSubviewToFront:self.indicatorView]; [self.scroll_view bringSubviewToFront:self.pullRefreshLabel];


这里的准备工作其实就是在scrollview里面先加入1个activityIndicator和1个label

下拉刷新

// 下拉刷新 - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{ if (scrollView.contentOffset.y < ⑸0 ) { [UIView animateWithDuration:1.0 animations:^{ // frame产生偏移,距离顶部50的距离(可自行设定) [scrollView setContentInset:UIEdgeInsetsMake(30, 0, 0, 0)]; [self.indicatorView startAnimating]; } completion:^(BOOL finished) { // 发起网络要求 ... [self.indicatorView stopAnimating]; [self.pullRefreshLabel setText:@"下拉刷新"]; [scrollView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)]; // 将当前页面置为1 currentPage = 1; }]; } } - (void)scrollViewDidScroll:(UIScrollView *)scrollView{ // 保持indecator的位置1直在顶端 if( scrollView.contentOffset.y < ⑸0){ [self.pullRefreshLabel setText:@"松开刷新"]; self.indicatorView.frame = CGRectMake(self.frame.size.width/2⑸0, scrollView.contentOffset.y+20 ,30, 30); self.pullRefreshLabel.frame = CGRectMake(self.frame.size.width/2⑵0, scrollView.contentOffset.y+20, 100, 30); }else{ self.indicatorView.frame = CGRectMake(self.frame.size.width/2⑸0, ⑶0 ,30, 30); self.pullRefreshLabel.frame = CGRectMake(self.frame.size.width/2⑵0, ⑶0, 100, 30); } }

注意两个代理不要用错了。1个是WillBeginDecelerating ,1个是didScroll

willBeginDecelerating就是我们往下拉scrollview然后松手的时候,这个代理方法会去检测当前scrollview的contentoffset,然后根据下拉的程度决定是不是进行刷新操作。这里我定义的阈值是50

然后为了使提示刷新的label和activityIndicator保持在1个固定的高度,就是不随着scrollview的往下拉而1直往下走,在didScroll代理里面计算了1下它们的位置。


上拉加载:

/ 上拉继续获得 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ /* * 关键--> * scrollView1开始其实不存在偏移量,但是会设定contentSize的大小,所以contentSize.height永久都会比contentOffset.y高1个手机屏幕的 * 高度;上拉加载的效果就是每次滑动到底部时,再往上拉的时候要求更多,那个时候产生的偏移量,就可以让contentOffset.y + 手机屏幕尺寸高大于这 * 个转动视图的contentSize.height */ if (scrollView.contentOffset.y + scrollView.frame.size.height >= scrollView.contentSize.height+50) { // [UIView commitAnimations]; [UIView animateWithDuration:1.0 animations:^{ // frame产生的偏移量,距离底部往上提高50(可自行设定) scrollView.contentInset = UIEdgeInsetsMake(0, 0, 50, 0); } completion:^(BOOL finished) { scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0); // 发送网络要求 currentPage ++; ... }]; } }














------分隔线----------------------------
------分隔线----------------------------

最新技术推荐