UITableView 下拉刷新的實(shí)現(xiàn)

UITableView下拉刷新的實(shí)現(xiàn)原理是自定義的下拉刷新控件KVO監(jiān)聽(tīng)UITableView(UIScrollView)的 contentOffset 屬性。

#import <UIKit/UIKit.h>

typedef void (^RefreshHeaderBlock)(void);

@interface RefreshHeader : UIView

- (instancetype)initWithTarget:(id)target beginRefreshBlock:(RefreshHeaderBlock)refreshHeaderBlock;

- (void)beginRefreshing;

- (void)endRefreshing;

@end

把UITableView(UIScrollView)傳進(jìn)來(lái)作為目標(biāo),添加監(jiān)聽(tīng)

@implementation RefreshHeader
- (instancetype)initWithTarget:(id)target beginRefreshBlock:(RefreshHeaderBlock)refreshHeaderBlock{
    self = [super init];
    if (self) {
        self.frame = CGRectMake(0, 0, 0, HeaderHeight);
        _refreshHeaderBlock = refreshHeaderBlock;

        _scrollView = (UIScrollView *)target;
        [_scrollView addSubview:self];
        NSKeyValueObservingOptions option = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
        [_scrollView addObserver:self forKeyPath:RefreshHeaderKeyPathContentOffset options:option context:nil];
    }
    return self;
}
- (void)layoutSubviews{
    [super layoutSubviews];
    CGFloat superWidth = self.scrollView.frame.size.width;
    self.frame = CGRectMake(0, - HeaderHeight, superWidth, HeaderHeight);
    ......
}

#pragma mark public
- (void)beginRefreshing{
    if (!_isRefresh) {
        
        _isRefresh = YES;
        
        //設(shè)置偏移量,銜接加載的更多數(shù)據(jù)
        [UIView animateWithDuration:0.3 animations:^{
            //刷新控件停留
            [_scrollView setContentInset:UIEdgeInsetsMake(HeaderHeight, 0, 0, 0)];
            
            [self.activityView startAnimating];
            self.arrowView.hidden = YES;
            self.stateLable.text = @"加載中";
        }];
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            _refreshHeaderBlock();
        });
    }
}

- (void)endRefreshing{
    _isRefresh = NO;
    
    [UIView animateWithDuration:0.3 animations:^{
        [self.activityView stopAnimating];
        self.arrowView.hidden = YES;
        self.arrowView.transform =  CGAffineTransformMakeRotation(M_PI*2);
        
        //還原scrollView
        [self.scrollView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    }];
}

#pragma mark KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    if ([keyPath isEqualToString:RefreshHeaderKeyPathContentOffset]) {
        [self scrollViewContentOffsetDidChange:change];
    }else{
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

#pragma mark logicol
//判斷contentOffset<0代表手勢(shì)為往下拖動(dòng),根據(jù)isDragging屬性判斷是否松開(kāi),如果松開(kāi)且偏移量大于(HeaderHeight),啟動(dòng)刷新動(dòng)作
- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change{
    
    self.stateLable.hidden = NO;
    CGFloat offset = self.scrollView.contentOffset.y;
    if (offset < 0) {
        //正在拖拽
        if(self.scrollView.isDragging){
            //還原scrollView
            [self.scrollView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)];
            
            [UIView animateWithDuration:0.3 animations:^{
                self.arrowView.hidden = NO;
                if (offset < -HeaderHeight*1.5) {
                    self.arrowView.transform =  CGAffineTransformMakeRotation(M_PI);
                    self.stateLable.text = @"釋放更新";
                }else{
                    self.arrowView.transform =  CGAffineTransformMakeRotation(M_PI*2);
                    self.stateLable.text = @"載入更多";
                }
            }];
            
            return;
        }
        
        //松開(kāi)且偏移量大于頭部高度,啟動(dòng)刷新
        if (offset < -HeaderHeight) {
            [self beginRefreshing];
        }
    }
}

-(void)dealloc{
    [self.scrollView removeObserver:self forKeyPath:RefreshHeaderKeyPathContentOffset];
}

demo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,259評(píng)論 4 61
  • 夏日,周遭黑的正濃烈,手機(jī)的熒光顯示此時(shí)凌晨一點(diǎn)二十四。短暫的假期以舟車勞頓,麻煩為理由,一次不回家。寧愿一個(gè)...
    山海ni閱讀 180評(píng)論 0 0
  • 坑1:“失火啦,失火啦” ,分別在寫(xiě)作業(yè)、寫(xiě)報(bào)告和看電視的一家人聽(tīng)到外面有人大喊,還伴有消防車的聲音,婆孫三個(gè)...
    power女神閱讀 244評(píng)論 0 2
  • 昨天在下廚房看到一段日食記的視頻,很有趣:日食記第一季第6集。雖然視頻中梅菜扣肉的做法被指不夠正宗,但短短視頻還是...
    115c3253903d閱讀 565評(píng)論 0 4
  • 題目1: \d,\w,\s,[a-zA-Z0-9],\b,.,*,+,?,x{3},^,$分別是什么? 題目2: ...
    蕭雪圣閱讀 185評(píng)論 0 0