美文网首页
尝试写表格刷新控件

尝试写表格刷新控件

作者: tangbin583085 | 来源:发表于2017-08-19 14:04 被阅读0次

没看MJRefresh源码前,自己尝试书写了UIScrollView(UITableView, UICollectionView)上拉,下拉刷新的功能,按照使用MJRefresh使用习惯,猜测实现的原理,然后写了3个类,简陋实现了的refresh(不可取,仅作学习参考)。

1,UITableView的分类

实现的思路,获取UITableVIew的代理,通过代理方法调用再次调用相应的自定义函数
获取代理

- (void)setTbHeader:(TBHeader *)tbHeader {
    
    // 设置对象
    tbHeader.tableView = self;
    _tbHeader = tbHeader;
    
    // 设置代理
    self.delegate = self;
    
    // 设置VC
    _viewController = [self findViewController:self];
}

代理调用自定义的方法,如:

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    
    // 执行头部代理
    if ([_tbHeader respondsToSelector:@selector(scrollViewDidEndDragging:willDecelerate:)]) {
        [_tbHeader scrollViewDidEndDragging:scrollView willDecelerate:decelerate];
    }
    
    // 执行尾部代理
    if ([_tbFooter respondsToSelector:@selector(scrollViewDidEndDragging:willDecelerate:)]) {
        [_tbFooter scrollViewDidEndDragging:scrollView willDecelerate:decelerate];
    }
    
    // 执行vc代理
    if ([_viewController respondsToSelector:@selector(scrollViewDidEndDragging:willDecelerate:)]) {
        [(UITableViewController *)_viewController scrollViewDidEndDragging:scrollView willDecelerate:decelerate];
    }
}

2,头部类TBHeader

实现思路,获取代理调用的contentoffset设置刷新状态

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    
    // 下拉伸进入刷新模式
    if (scrollView.contentOffset.y < -scrollView.contentInset.top - pullToRefreshHeight && !self.isFreshing) {
        
        // 开启刷新
        [self headerBeginRefresh];
        
        
        // 正在刷新
        dispatch_async(dispatch_get_main_queue(), ^{
            //  NSLog(@"*****禁止惯性滚动*************Start reFresh**************************");
            
            [scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, -scrollView.contentInset.top - refreshHeaderHeight) animated:YES];
        });
        
    }
    // 解决下拉正在刷新
    else if(scrollView.contentOffset.y < - scrollView.contentInset.top - pullToRefreshHeight && self.isFreshing){
        // 正在刷新
        dispatch_async(dispatch_get_main_queue(), ^{
            //  NSLog(@"*****禁止惯性滚动*************Start reFresh**************************");
            
            [scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, -scrollView.contentInset.top - refreshHeaderHeight) animated:YES];
        });
    }

    // 上拉刷新
    else if (self.tableView.contentOffset.y + [UIScreen mainScreen].bounds.size.height >= self.tableView.contentSize.height + pullToRefreshHeight) {
        
    }
    
    NSLog(@"%@", NSStringFromCGPoint(self.tableView.contentOffset));
}

在原来的表格HeaderView再添加刷新UIView(后来发现不可取)

- (void)replaceNewHeader {
    
    if (self.NewheaderViewTemp != self.tableView.tableHeaderView || !self.NewheaderViewTemp) {
        UIView *NewheaderViewTemp = [[UIView alloc] init];
        NewheaderViewTemp.backgroundColor = [UIColor colorWithWhite:0.5 alpha:1.0];
        self.NewheaderViewTemp = NewheaderViewTemp;
        
        UIView *headerViewOriginal = self.tableView.tableHeaderView;
        NSLog(@"%@", headerViewOriginal);
        self.tableView.tableHeaderView = nil;
        
        
        UIButton *headerBtnView = [UIButton buttonWithType:UIButtonTypeCustom];
        headerBtnView.backgroundColor = [UIColor purpleColor];
        headerBtnView.titleLabel.textAlignment = NSTextAlignmentCenter;
        [headerBtnView setTitle:@"下拉刷新" forState:UIControlStateNormal];
        [headerBtnView addTarget:self action:@selector(headerBeginRefresh) forControlEvents:UIControlEventTouchUpInside];
        self.headerBtnView = headerBtnView;
        headerBtnView.frame = CGRectMake(0, 0, self.tableView.width, refreshHeaderHeight);
        headerViewOriginal.y = headerBtnView.height;
        [NewheaderViewTemp addSubview:headerBtnView];
        //    [headerViewOriginal removeFromSuperview];
        NewheaderViewTemp.height = headerViewOriginal.height + headerBtnView.height;
        [NewheaderViewTemp addSubview:headerViewOriginal];
        self.tableView.tableHeaderView = NewheaderViewTemp;
        
        // 重新设置inset
        [self.tableView setContentInset:UIEdgeInsetsMake(self.tableView.contentInset.top - headerBtnView.height, 0, self.tableView.contentInset.bottom, 0)];
    }
}

3,尾部类TBFooter

实现思路和Header相似
根据contentOffset设置状态加载更多

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    // 上拉刷新
    if (self.tableView.contentOffset.y + self.tableView.height - self.tableView.contentInset.bottom >= self.tableView.contentSize.height + pullToRefreshHeight && !self.isFreshing) {
        
        [self footerBeginRefresh];
    }
    
    NSLog(@"%@", NSStringFromCGPoint(self.tableView.contentOffset));
}

总结

1, 功能虽然是实现了,但是存在很多不足之处。
2,改变了UISrollView的真正代理对象。
3,改变了HeadView和FooterView,相应地改变了contentInset
4,可能会中断开发者UISrollView 代理方法。
自己尝试写了一遍,发现和源码MJRefresh对比之后自己的不足之处,才能领会他人的精粹,方能不断进步

附上自己尝试写的表格刷新代码(不可取,只是为了学习参考)!
https://github.com/tangbin583085/TBScrollViewRefresh

相关文章

网友评论

      本文标题:尝试写表格刷新控件

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