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

简介:

下拉刷新功能基本上在所有的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 ++;
            ...
        }];
    }
}














目录
相关文章
|
Android开发
【原理篇】WebView 实现嵌套滑动,丝滑般实现吸顶效果,完美兼容 X6 webview(一)
【原理篇】WebView 实现嵌套滑动,丝滑般实现吸顶效果,完美兼容 X6 webview
|
Android开发
【原理篇】WebView 实现嵌套滑动,丝滑般实现吸顶效果,完美兼容 X6 webview(二)
【原理篇】WebView 实现嵌套滑动,丝滑般实现吸顶效果,完美兼容 X6 webview
|
Android开发
【原理篇】WebView 实现嵌套滑动,丝滑般实现吸顶效果,完美兼容 X5 webview
【原理篇】WebView 实现嵌套滑动,丝滑般实现吸顶效果,完美兼容 X5 webview
|
4天前
|
容器
Flutter下拉刷新上拉加载的简单实现方式一
Flutter下拉刷新上拉加载的简单实现方式一
12 2
|
6月前
|
监控
如何解决UICollectionView不能下拉刷新问题
如何解决UICollectionView不能下拉刷新问题
90 0
|
6月前
|
JavaScript
原生js如何实现上拉加载下拉刷新?
原生js如何实现上拉加载下拉刷新?
38 0
|
JavaScript API 开发者
uniapp滚动加载 下拉刷新
在日常开发中,滚动加载和下拉刷新是非常常见的功能,页面数据过多时,需要滚动加载优化性能,本篇技术分享博客将介绍如何在uniapp中实现滚动加载和下拉刷新。至此,我们已经成功地实现了滚动加载和下拉刷新两种常见的移动端功能。大家可以进行扩充或者留言交流!通过以上示例代码,我们可以看到uniapp提供了非常方便的API来实现这些功能,使得开发者可以更加专注于业务逻辑的实现。
242 0
|
Android开发
WebView 实现嵌套滑动,丝滑般实现吸顶效果,完美兼容 X5 webview
WebView 实现嵌套滑动,丝滑般实现吸顶效果,完美兼容 X5 webview
188 0
WebView 实现嵌套滑动,丝滑般实现吸顶效果,完美兼容 X5 webview
|
前端开发
Flutter 之列表下拉刷新和上拉加载
在实际的 App 中,下拉刷新和上滑加载更多是非常常见的交互形式。在 Flutter 中,有 flutter_easyrefresh开源插件用于实现下拉刷新和上滑加载更多。本篇介绍了有状态组件和 flutter_easyrefresh 的基本应用,同时使用模拟的方式完成了异步数据加载。
700 0
Flutter 之列表下拉刷新和上拉加载
|
iOS开发
iOS开发 - 让tableView不能下拉刷新,可以上拉加载
iOS开发 - 让tableView不能下拉刷新,可以上拉加载
307 0