ios拓展23-自定义下拉刷新(原理)

作者: Abler | 来源:发表于2016-08-22 18:53 被阅读1285次

    ios开发中,刷新数据很常见.但是系统tableView提供的如果不符合我们的要求,那就需要自己自定义控件刷新.像MJRefresh就很有名. 这里我们可以仿照系统自己写一个。

    (原理效果图)自定义一个refreshControl控件,继承自 UIControl

    1.在refreshControl中获取将要加载到的父类视图,强转为scrollView, 一般添加到tableView上,也转为scrollView
    /**
     *  获取将要加载到的父类视图
     *
     *  @param newSuperview 父View
     */
    -(void)willMoveToSuperview:(UIView *)newSuperview{
        //通过kvo,监听滚动
        if (newSuperview) {
            // 获取View进行强转, 通过kvo监听滚动
            self.scrollView = (UIScrollView *)newSuperview;
            // 监听scrollView的contentOffset
            [self.scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
        }
        
    }
    
    2. 通过kvo,监听scrollView偏移量, 对其内部进行改变
    /**
     *  监听方法
     */
    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
        [self refreshChangeState];
    }
    /**
     *  通过监听当前scrollView的状态,来改变refreshControl控件的状态
     */
    - (void)refreshChangeState{
        CGFloat offsetY = self.scrollView.contentOffset.y;
        // 用户是否在拖动
        if (self.scrollView.dragging) {
            if (offsetY > -128) {//这里的数值是根据frame来的
                self.label.text = @"正常";
            }else if(offsetY <= -128){
                self.label.text = @"下拉中";
            }
        }
    }
    
    原理效果图

    具体效果图
    具体效果思路实现:细节以及源码(只是用来说明原理的,备注很详细)
    • 1.在监听滚动后,定义一个属性,记录其状态
    typedef NS_ENUM(NSInteger,YYRrefreshControlState) {
        Normal = 0,
        Pulling = 1,
        Rrefreshing = 2,
    };
    
    @property (nonatomic, assign) YYRrefreshControlState refreshState;
    
    • 2.重写状态的setter方法,
    /**
     *  刷新状态发生改变,进行对应的修改
     *
     *  @param refreshState 刷新状态
     */
    -(void)setRefreshState:(YYRrefreshControlState)refreshState{
        // 这句话千万不能少,
        _refreshState = refreshState;
        UIEdgeInsets inset = self.scrollView.contentInset;
        
        switch (refreshState) {
            case Normal:
            {
                self.label.text = @"正常";
              
                if (self.oldState == Rrefreshing) {//======= 这里要做判断, 不然会有bug
                    [UIView animateWithDuration:0.5 animations:^{
                        self.scrollView.contentInset = UIEdgeInsetsMake(inset.top - 64, inset.left, inset.bottom, inset.right);
                    } completion:^(BOOL finished) {
                        
                    }];
                }
            }
                break;
            case Pulling:
                self.label.text = @"下拉中";
                break;
            case Rrefreshing:
            {
                // 告知外界刷新了,相当于发送通知
                [self sendActionsForControlEvents:UIControlEventValueChanged];
                
                // 动画效果
                [UIView animateWithDuration:0.5 animations:^{
                    self.scrollView.contentInset = UIEdgeInsetsMake(inset.top + 64, inset.left, inset.bottom, inset.right);
                    
                } completion:^(BOOL finished) {
    
                }];
            }
                break;
            default:
                break;
        }
        
        self.oldState = refreshState;//======用来做判断的
        
    }
    
    • 3.YYRrefreshControl提供一个可供外界调用的endRefreshing方法(为什么提供,仿照系统写的)
    .h
    @interface YYRrefreshControl : UIControl
    /**
     *  提供给外界调用的方法
     */
    - (void)endRefreshing;
    @end
    
    .m
    /**
     *  提供给外界调用的方法,  .h文件里面声明这个方法
     */
    - (void)endRefreshing{
        // 1.把状态改为正常
        self.refreshState = Normal;
        // 2.恢复contentInset
            // 2.1在setter方法里面修改
    //  -(void)setRefreshState:(YYRrefreshControlState)refreshState
    }
    
    • 4.在外界接收通知
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // 相当于接收通知
        [self.refreshControl addTarget:self action:@selector(did) forControlEvents:UIControlEventValueChanged];
        
        [self.tableView addSubview:self.refreshControl];
        
    }
    
    // 接收通知监听的方法
    - (void)did{
            [self.refreshControl endRefreshing];
    }
    

    相关文章

      网友评论

        本文标题:ios拓展23-自定义下拉刷新(原理)

        本文链接:https://www.haomeiwen.com/subject/vohgsttx.html