• iOS ScrollView 下拉放大 升级 带上下拉刷新


    在上一篇《iOS ScrollView 下拉放大》已经介绍了基本的下拉放大,接下来再加上下拉刷新

    定义下拉刷新状态

    typedef enum {
    
        RefreshStateIdle,
    
        RefreshStatePullRefresh,
    
        RefreshStateReadyRefresh,
    
        RefreshStateRefreshing
    
    
    } RefreshState;

     

    定义下拉刷新需使用的变量

    {
        
        // Refresh
        UILabel *_refreshLabel;
        RefreshState _refreshState;
        CGFloat _refreshHeight;
    }

    下拉刷新的实现是在下拉刷的新阀值detal小于下拉放大阀值alpha的基础上进行的,接下来就初始化下拉刷新的变量了

        _refreshState = RefreshStateIdle;
        _refreshHeight = 40;
        
        _refreshLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, -    
        _refreshHeight, self.view.bounds.size.width, _refreshHeight)];
        _refreshLabel.textAlignment = NSTextAlignmentCenter;
        _refreshLabel.textColor = [UIColor redColor];
        _refreshLabel.text = @"刷新...";
        [self.view addSubview:_refreshLabel];

    然后改造ScrollView代理方法了,在处理下拉放大的过程中同时处理下拉刷新

    #pragma mark - ScrollView Delegate
    
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        
        if (_refreshState == RefreshStateRefreshing) {
            return;
        }
        
        CGFloat offsetY = scrollView.contentOffset.y;
        NSLog(@"offsetY: %f",offsetY);
        
        CGFloat top = scrollView.contentInset.top;
        
        if (!_zoomIn) {
            if (offsetY < -top) { // 下拉
                CGRect frame = _zoomView.frame;
                frame.origin.y = offsetY;
                frame.size.height = -offsetY;
                _zoomView.frame = frame;
                
                // 处理下拉
                if (_refreshState != RefreshStateRefreshing && !_decelerating) {
                    frame = _refreshLabel.frame;
                    frame.origin.y = -offsetY - top;
                    _refreshLabel.frame = frame;
                    
                    if ((-offsetY - top) < _refreshHeight) {
                        [self setRefreshState:RefreshStatePullRefresh];
                    } else {
                        [self setRefreshState:RefreshStateReadyRefresh];
                    }
                }
                
                
                if (!_decelerating && -offsetY > 1.9 * _zoomHeight) {
                    
                    [self setRefreshState:RefreshStateIdle];
                    frame.origin.y = -_refreshHeight;
                    _refreshLabel.frame = frame;
                    
                    scrollView.contentInset = UIEdgeInsetsMake(scrollView.bounds.size.height, 0, 0, 0);
                    frame.origin.y = -scrollView.bounds.size.height;
                    frame.size.height = scrollView.bounds.size.height;
                    _zoomView.frame = frame;
                    
                    _zoomIn = YES;
                    scrollView.contentSize = CGSizeMake(0, 1); // 使上拉有弹簧效果
                }
            }
        } else { // 上拉
            if (!_decelerating && (offsetY + top) / top > 0.3) {
                
                scrollView.contentInset = UIEdgeInsetsMake(_zoomHeight, 0, 0, 0);
                CGRect frame = _zoomView.frame;
                frame.origin.y = -_zoomHeight;
                frame.size.height = _zoomHeight;
                _zoomView.frame = frame;
                
                _zoomIn = NO;
                scrollView.contentSize = CGSizeMake(0, _contentSize.height); // 恢复正常
            }
        }
    
    }
    
    - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
        _decelerating = YES;
    }
    
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
        _decelerating = NO;
    }
    
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
        
        if (_refreshState == RefreshStateRefreshing) {
            return;
        }
        
        CGRect frame = _refreshLabel.frame;
        if (_refreshState == RefreshStateReadyRefresh) {
            [self setRefreshState:RefreshStateRefreshing];
            frame.origin.y = 0;
        } else {
            [self setRefreshState:RefreshStateIdle];
            frame.origin.y = -_refreshHeight;
        }
        _refreshLabel.frame = frame;
    }
    
    #pragma mark - Refresh
    
    - (void)setRefreshState:(RefreshState)state {
        _refreshState = state;
        
        if (_refreshState == RefreshStateIdle) {
            _refreshLabel.text = @"下拉刷新";
        } else if (_refreshState == RefreshStatePullRefresh) {
            _refreshLabel.text = @"下拉刷新";
        } else if (_refreshState == RefreshStateReadyRefresh) {
            _refreshLabel.text = @"松开刷新";
        } else if (_refreshState == RefreshStateRefreshing) {
            _refreshLabel.text = @"刷新...";
            [self loadData];
        }
    }

    处理滑动的过程中,如果当前正在刷新那么立即返回。下拉过程中根据offsetY值判断到达阀值,在到达刷新阀值detal后并且没有达到放大阀值alpha,那么松手的时候就进入刷新状态,没有达到下拉刷新阀值detal就松手的情况下就恢复正常。如果在达到下拉刷新阀值detal后继续下拉到达放大阀值,那么就将刷新状态置为idle,同时隐藏刷新View,做放大操作。

    当然,刷新完成后还要报告刷新完成,以处理刷新View

    #pragma mark - Load Data
    
    - (void)loadData {
        
        __weak typeof(self) weakSelf = self;
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
           
            sleep(5);
            
            dispatch_async(dispatch_get_main_queue(), ^{
                if (weakSelf) {
                    __strong typeof(weakSelf) strongSelf = weakSelf;
                    
                    [strongSelf refreshFinish];
                }
                
            });
            
        });
    }
    
    - (void)refreshFinish {
        
        [self setRefreshState:RefreshStateIdle];
        CGRect frame = _refreshLabel.frame;
        frame.origin.y = -_refreshHeight;
        _refreshLabel.frame = frame;
    }
  • 相关阅读:
    BFC——块级格式化上下文
    深入浅出——float
    NodeJS 学习记录
    JavaScript高级程序设计 第六章 面向对象程序设计
    软件项目管理课感想
    第八周PSP 新折线图和饼图 个人时间管理
    第七周PSP 新折线图和饼图 个人时间管理
    Alpha、伪Beta 发布个人感想与体会
    ”单元测试“理解与感悟
    编程
  • 原文地址:https://www.cnblogs.com/buakaw/p/9055895.html
Copyright © 2020-2023  润新知