自定义刷新控件

区别几个属性,拖拽

  • decelerating: 用户没有在拖拽,但滚动视图仍然是移动
  • dragging: 用户已经开始滚动。这可能需要一段时间或距离转变为拖拽
  • tracking: 用户已经触碰了,可能还没开始拖拽

1.上拉刷新

  • 定义一些属性: 1.是否正在刷新,2.进度,3.scrollview,4.刷新操作block,5.子控件
@property(nonatomic,strong)UIImageView *cloudImageView2;
@property(nonatomic,strong)UIImageView *cloudImageView3;
.....

@property(nonatomic,assign)CGFloat         progress;//进度
@property(nonatomic,assign)BOOL            isRefreshing;//是否正在刷新
@property(nonatomic,weak  )UIScrollView    *scrollView;//注意:这里要用weak
@property(nonatomic,copy  )Ly_heardRefresh ly_heardRefresh; 
  • 初始化方法
+ (instancetype)heardRefreshWithBlock:(Ly_heardRefresh)heardRefresh
{
    LyRefreshView *heard = [[LyRefreshView alloc] init];
    heard.ly_heardRefresh = heardRefresh;
    return heard;
}

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        self.progress = 0.0;
        self.isRefreshing = NO;
        //设置默认属性,添加子控件
    }
    return self;
}
- (void)dealloc
{
    if (self.scrollView) {
        [self.scrollView removeObserver:self forKeyPath:@"contentOffset"];
    }
}

 

  • 在移入父控件的方法中做操作 willMoveToSuperview,didMoveToSuperview
- (void)willMoveToSuperview:(UIView *)newSuperview
{
    [super willMoveToSuperview:newSuperview];
    
    if (!newSuperview) {
        [self.superview removeObserver:self forKeyPath:@"contentOffset"];
    }
}

- (void)didMoveToSuperview
{
    [super didMoveToSuperview];
    
    UIView *superView = self.superview;
    if ([superView isKindOfClass:[UIScrollView class]])
    {
        self.scrollView = (UIScrollView *)superView;
    }
}

 

  • 重写scrollview的set方法,添加kvo监听滑动
- (void)setScrollView:(UIScrollView *)scrollView
{
    _scrollView = scrollView;
    
    [self setupImageView:scrollView];
}

- (void)setupImageView:(UIScrollView *)scrollView
{
    self.frame = CGRectMake(0, -200, scrollView.bounds.size.width, 200);
//    [scrollView insertSubview:self atIndex:0];
    [scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];

.....
}
  • 监听kvo
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    if (self.isRefreshing) {
        return;
    }
    
    if (object == self.scrollView && [keyPath isEqualToString:@"contentOffset"])
    {
        if (self.scrollView.decelerating && self.progress >= 1.0)//停止了拖拽,但还在滑动
        {
            NSLog(@"停止了拖拽,但还在滑动");
            //开始刷新,开始刷新做的一些操作
            [self beginRefreshing];
            
            if (self.ly_heardRefresh) {
                self.ly_heardRefresh();
            }
            if ([self.delegate respondsToSelector:@selector(lyRefreshViewWithHeardRefreshing:)]) {
                [self.delegate lyRefreshViewWithHeardRefreshing:self];
            }
            
            return;
        }
        NSLog(@"将要刷新");
        //1.先拿到刷新视图可见区域的高度
        CGFloat h = MAX(0, -self.scrollView.contentOffset.y - self.scrollView.contentInset.top);
        //2.求进度
        self.progress = MIN(1, h / kSceneHeight);
        //3.更新视图
        [self updateBackgroundColor];
    }
}

 

  • 开始刷新
- (void)beginRefreshing
{
    self.isRefreshing = YES;
    [self updateRefreshItemPositions];
    
    //停滞,显示刷新视图
    [UIView animateWithDuration:0.4 animations:^{
        UIEdgeInsets edge = self.scrollView.contentInset;
        edge.top += kSceneHeight;
        self.scrollView.contentInset = edge;
    } completion:^(BOOL finished) {
        
    }];
...动画什么的
}

 

  • 结束刷新
- (void)endRefreshing
{
    [UIView animateWithDuration:0.4 animations:^{
        UIEdgeInsets edge = self.scrollView.contentInset;
        edge.top -= kSceneHeight;
        self.scrollView.contentInset = edge;
    } completion:^(BOOL finished) {
        self.isRefreshing = NO;
    }];
...刷新的时候改变的东西,最后别忘了还原
}

2.下拉刷新

  • view的Y应该是:CGFloat y = self.scrollView.contentSize.height + self.scrollView.contentInset.bottom;

  • 置停
  • [UIView animateWithDuration:0.2 animations:^{
                UIEdgeInsets edge = self.scrollView.contentInset;
                edge.bottom += self.frame.size.height;
                self.scrollView.contentInset = edge;
            } completion:^(BOOL finished) {
                
            }];

     

 demo: https://github.com/zhangjie579/LyRefresh

posted @ 2017-04-23 16:37  ZJea  阅读(303)  评论(0编辑  收藏  举报