• iOS 下拉刷新-上拉加载原理


    前言

    讲下拉刷新及上拉加载之前先给大家解释UIScrollView的几个属性

    • contentSize是UIScrollView可以滚动的区域。
    • contentOfinset 苹果官方文档的解释是"内容视图嵌入到封闭的滚动视图的距离,我的理解是他实际上就是scrollView的Content View相对于scrollView的外壳的边距,他其实和CSS中的pading属性有点相似。
    • contentOffset是UIScrollView当前显示区域的顶点相对于frame顶点的偏移量,例如上面的例子如果拉到最下面,则contentOffset就是(0, 480),也就是y偏移了480.

    下拉刷新及上拉加载原理

    • 下拉刷新实际上是监测UIScrollViewcontentOffset的y值,当他往下拉动时,UIScrollViewcontentOffset是一直减小的,然后把通过动画把它的contentInset值控制成一个定值,然后通过设置延时来把UIScrollView的contentInset的值恢复原点。啥话不说,上代码
    //下拉刷新
      
        if (scrollView.contentOffset.y < -100) {
            
            [UIView animateWithDuration:1.0 animations:^{
                
                self.scrollView.contentInset = UIEdgeInsetsMake(100, 0, 0, 0);
                
            } completion:^(BOOL finished) {
                
                NSLog(@"发起下拉刷新");
                
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    
                    [UIView animateWithDuration:1.0 animations:^{
                        
                        self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
    
                    }];
                    
                });
                
            }];
        
        }
    • 上拉加载其实原理和下拉刷新基本是一样的,只不过判断的contentOffset的值不同,如果scrollView.bounds.size.height +  scrollView.contentOffset.y >scrollView.contentSize.height,说明你执行了上拉操作,然后实现起来基本就和下拉刷新是一样的。
    //上拉加载
        
        if (scrollView.bounds.size.height +  scrollView.contentOffset.y >scrollView.contentSize.height) {
            
            [UIView animateWithDuration:1.0 animations:^{
                
                self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 50, 0);
                
            } completion:^(BOOL finished) {
                
                NSLog(@"发起上拉加载");
                
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    
                    [UIView animateWithDuration:1.0 animations:^{
                        
                        self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
                        
                    }];
                });
            }];
            
            
        }

    下面奉上完整的demo代码,大家看不懂的可以私聊我,要是想深入了解的话可以去github搜索MJRefresh看完整的别人封装好的第三方

    #import "ViewController.h"
    
    @interface ViewController ()<UIScrollViewDelegate>
    
    @property (nonatomic, strong) UIScrollView * scrollView;
    
    @end
    
    @implementation ViewController
    
    - (UIScrollView *)scrollView {
        
        if (!_scrollView) {
            _scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
            
            //contentSize是可滑动的区域
            _scrollView.contentSize = CGSizeMake(0, 900);
            _scrollView.backgroundColor = [UIColor grayColor];
            _scrollView.delegate = self;
            
            //greenView实际上就是UIScrollView的content View
            UIView * greenView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 900)];
            greenView.backgroundColor = [UIColor greenColor];
            [_scrollView addSubview:greenView];
            
        }
        return _scrollView;
    }
    
    - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
        
        
        //下拉刷新-当下拉刷新时,contentOffset实际上就是greenView相对于屏幕左上角的偏移量。
        if (scrollView.contentOffset.y < -100) {
            
            [UIView animateWithDuration:1.0 animations:^{
                
                self.scrollView.contentInset = UIEdgeInsetsMake(100, 0, 0, 0);
                
            } completion:^(BOOL finished) {
                
                NSLog(@"发起下拉刷新");
                
                //设置延时时间为2秒
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    
                    [UIView animateWithDuration:1.0 animations:^{
                        //恢复之前的contentInset,让greenView回到原来的地方
                        self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
    
                    }];
                    
                });
                
            }];
        
        }
        
        //上拉加载
        
        if (scrollView.bounds.size.height +  scrollView.contentOffset.y >scrollView.contentSize.height) {
            
            [UIView animateWithDuration:1.0 animations:^{
                
                self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 50, 0);
                
            } completion:^(BOOL finished) {
                
                NSLog(@"发起上拉加载");
                
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    
                    [UIView animateWithDuration:1.0 animations:^{
                        
                        self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
                        
                    }];
                });
            }];
            
            
        }
        
    }
    
    
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        [self.view addSubview:self.scrollView];
        
        
        
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
  • 相关阅读:
    netcore 发布到IIS上常见错误
    mysql解压文件安装
    VS2017 怎么启用nuget程序包还原?
    vue-qr生成下载二维码
    控制器,action, 过滤器, 权限
    WebSocket浅析(一):实现群聊功能
    BOM元素之window对象
    arguments及arguments.callee
    Spring入门6事务管理2 基于Annotation方式的声明式事务管理机制
    Spring入门5.事务管理机制
  • 原文地址:https://www.cnblogs.com/ldnh/p/5313374.html
Copyright © 2020-2023  润新知