博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
不借助第三方插件利用ScrollView自身delegate实现下拉刷新和上拉加载
阅读量:5978 次
发布时间:2019-06-20

本文共 3389 字,大约阅读时间需要 11 分钟。

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

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

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

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

准备工作:

// 设置下拉刷新的process和label    self.indicatorView = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(self.frame.size.width/2 - 50, -25, 20, 20)];    [self.indicatorView setColor:[UIColor blackColor]];    self.pullRefreshLabel = [[UILabel alloc]initWithFrame:CGRectMake(self.frame.size.width/2 -20, -30, 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里面先加入一个activityIndicator和一个label

下拉刷新

// 下拉刷新- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{    if (scrollView.contentOffset.y < -50 ) {        [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的位置一直在顶端    if( scrollView.contentOffset.y < -50){        [self.pullRefreshLabel setText:@"松开刷新"];        self.indicatorView.frame = CGRectMake(self.frame.size.width/2-50, scrollView.contentOffset.y+20 ,30, 30);        self.pullRefreshLabel.frame = CGRectMake(self.frame.size.width/2-20, scrollView.contentOffset.y+20, 100, 30);    }else{        self.indicatorView.frame = CGRectMake(self.frame.size.width/2-50, -30 ,30, 30);        self.pullRefreshLabel.frame = CGRectMake(self.frame.size.width/2-20, -30, 100, 30);    }}
注意两个代理不要用错了。一个是WillBeginDecelerating ,一个是didScroll

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

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

上拉加载:

/ 上拉继续获取- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{    /*     *  关键-->     *  scrollView一开始并不存在偏移量,但是会设定contentSize的大小,所以contentSize.height永远都会比contentOffset.y高一个手机屏幕的     *  高度;上拉加载的效果就是每次滑动到底部时,再往上拉的时候请求更多,那个时候产生的偏移量,就能让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 ++;            ...        }];    }}

转载地址:http://drpox.baihongyu.com/

你可能感兴趣的文章
Mybatis调用Oracle中的存储过程和function
查看>>
基本安装lnmp环境
查看>>
yum源资料汇总
查看>>
7、MTC与MTV,http请求介绍
查看>>
logstash消费阿里云kafka消息
查看>>
unix 环境高级编程
查看>>
MAXIMO 快速查找实现
查看>>
Oracle——条件控制语句
查看>>
day-6 and day-7:面向对象
查看>>
CSU Double Shortest Paths 湖南省第十届省赛
查看>>
webgl像机世界
查看>>
php正则怎么使用(最全最细致)
查看>>
javascript数学运算符
查看>>
LC.155. Min Stack(非优化,两个stack 同步 + -)
查看>>
交互设计[3]--点石成金
查看>>
SCCM TP4部署Office2013
查看>>
redis主从配置<转>
查看>>
bootloader功能介绍/时钟初始化设置/串口工作原理/内存工作原理/NandFlash工作原理...
查看>>
利用console控制台调试php代码
查看>>
讲解sed用法入门帖子
查看>>