iOS—Object_C-上下刷新工具類_解析

刷新工具類.png

效果圖--------

開始刷新.png
點(diǎn)擊加載更多.png

下拉刷新視圖.png

上拉刷新.png

實(shí)現(xiàn)思路

結(jié)構(gòu)解析

一、下拉刷新實(shí)現(xiàn)

導(dǎo)入#import "UIScrollView+CLRefreshView.h",添加滾動(dòng)視圖的刷新效果,在基類中創(chuàng)建刷新工具類,以便子類UITableViewUIScrollView通用。

/** 下拉刷新 */
- (void)setUpSimpleHeader{
    __weak typeof (self) weakSelf = self;
    [self.tabelview cl_addRefreshHeaderViewWithAction:^{
        [weakSelf loadHeaderData:kLoadOptionHeader];
    }];  
}

在分類中,因?yàn)椴荒芴砑訉傩裕?code>#import <objc/runtime.h>使用runtime機(jī)制,將vc上傳入的滾動(dòng)視圖,進(jìn)行刷新視圖綁定

- (void)setCl_refreshHeader:(CLRefreshHeader *)cl_refreshHeader{
    [self willChangeValueForKey:@"CLRefreshHeaderViewKey"];
    objc_setAssociatedObject(self, &CLRefreshHeaderViewKey, cl_refreshHeader,OBJC_ASSOCIATION_ASSIGN);
    [self didChangeValueForKey:@"CLRefreshHeaderViewKey"];
}
- (CLRefreshHeader *)cl_refreshHeader{
    return objc_getAssociatedObject(self, &CLRefreshHeaderViewKey);
}

通過set方法將傳入的滾動(dòng)視圖,綁定& CLRefreshHeaderViewKey唯一標(biāo)識(shí)。這里針對(duì)的是唯一字符串的地址空間,這樣的好處是不會(huì)重復(fù)綁定。實(shí)現(xiàn)了唯一性。字符串static char CLRefreshHeaderViewKey;

一、具體實(shí)現(xiàn)思路:CLAbstractRefreshView抽象類,執(zhí)行刷新狀態(tài)的監(jiān)聽

/** 不同時(shí)機(jī)下的刷新狀態(tài) */
typedef enum {
    CLRefreshViewStateNormal = 1,//滾動(dòng)視圖滑動(dòng)但是,未觸發(fā)加載時(shí)機(jī)
    CLRefreshViewStateWillLoading,//滾動(dòng)視圖滑動(dòng),且觸發(fā)到最大下拉距離的時(shí)機(jī)
    CLRefreshViewStateLoading//正在加載中
}CLRefreshViewState;
編寫下拉刷新的關(guān)鍵是考慮contentOffset以及contentInsert,前者用來判斷當(dāng)前手勢(shì)下滑進(jìn)行的進(jìn)度和程度,從而去判斷刷新視圖進(jìn)行的狀態(tài)變化,并借由它將進(jìn)度傳入動(dòng)畫視圖去執(zhí)行動(dòng)畫流程。
動(dòng)畫視圖.png
/** 抽象類中的基本協(xié)議 */
@protocol CLRefreshControl <NSObject>

@optional
- (void)refreshViewChangeUIWhenNormal;//執(zhí)行 1
- (void)refreshViewChangeUIWhenWillLoading;//執(zhí)行 2
- (void)refreshViewChangeUIWhenLoading;//執(zhí)行 3
- (void)refreshViewChangeUIWhenFinishLoading;// 滾動(dòng)視圖復(fù)位
@end
/** 這是一個(gè)刷新的抽象類 */
@class CLAbstractLoadingView;
@interface CLAbstractRefreshView : UIView<CLRefreshControl>
@property (nonatomic, weak, readonly) UIScrollView *scrollView;
@property (nonatomic, assign, readonly) UIEdgeInsets scrollViewOriginalInserts;//記錄滾動(dòng)視圖的原始Insets
@property (nonatomic, copy) void (^refreshAction)();
@property (nonatomic, assign) CLRefreshViewState state;//記錄當(dāng)前刷新的狀態(tài)
@property (nonatomic, assign, readonly) CLRefreshViewState previousState;//記錄之前的刷新狀態(tài)
/** 加載動(dòng)畫視圖 */
@property (nonatomic, weak) CLAbstractLoadingView *loadingView;
/** 獲取當(dāng)前滾動(dòng)視圖里下拉時(shí)機(jī)的進(jìn)度 */
@property (nonatomic, assign, readonly) CGFloat showProgress;
/** 創(chuàng)建下拉視圖 */
+ (instancetype)refreshView;
- (void)endRefresh;//結(jié)束和開始刷新是,提供的抽象方法,是通用的
- (void)startRefresh;
#pragma mark -子類實(shí)現(xiàn)
/**
 *  根據(jù)滾動(dòng)視圖的屬性計(jì)算出,空間將要顯示的位置
 *
 *  @param scrollViewInsets <#scrollViewInsets description#>
 *  @param offset           <#offset description#>
 *
 *  @return 控價(jià)顯示的百分比進(jìn)度,如果控件直接處與屏幕外,返回-1.父類默認(rèn)返回-1
 */
- (CGFloat)showProgress:(UIEdgeInsets)scrollViewInsets scrollViewOffset:(CGPoint)offset;
/**
 *  控件將要顯示的位置,由Header子類實(shí)現(xiàn),F(xiàn)ooter子類此方法無意義
 *
 *  @return 控件剛加入滾動(dòng)視圖時(shí),將要顯示的位置,默認(rèn)返回(0,0)
 */
- (CGPoint)willShowPoint;

使用多態(tài),提高程序的可讀性。

子類CLSimpleRefreshHeader( 這個(gè)類主要去實(shí)現(xiàn)細(xì)節(jié),比如不同時(shí)機(jī)下的提示語句,還有創(chuàng)建動(dòng)畫視圖),父類CLRefreshHeader (實(shí)現(xiàn)對(duì)視圖不同狀態(tài)下,位置的設(shè)置),抽象類CLAbstractRefreshView(監(jiān)聽手勢(shì)滑動(dòng)去實(shí)現(xiàn)刷新視圖狀態(tài)的改變以及動(dòng)畫視圖的繪制進(jìn)度調(diào)整)
子類CLCircleLoadingView(繪制動(dòng)畫),抽象類CLAbstractLoadingView(設(shè)置繪畫的進(jìn)度)

/** 提供添加下拉刷新的視圖 */
- (void)cl_addRefreshHeaderViewWithAction:(void(^)())action{
    CLRefreshHeader *header = [CLSimpleRefreshHeader refreshView];
    header.refreshAction = action;
    [self cl_addRefreshHeaderView:header];
}

二、上拉刷新

子類CLSimpleRefreshFooter(創(chuàng)建動(dòng)畫視圖CLCircleLoadingView),父類CLRefreshFooter(通過上拉狀態(tài)設(shè)置滾動(dòng)視圖的固定位置),抽象類CLAbstractRefreshView(設(shè)置不同的刷新狀態(tài)監(jiān)聽)。
注意的一點(diǎn):上拉刷新在界面內(nèi)容過少的時(shí)候,應(yīng)該顯示“加載更多的提示按鈕”。與下拉通過contentOffset不同現(xiàn)在監(jiān)聽的是滾動(dòng)視圖的contentSize。

具體的代碼解析 ,我已經(jīng)寫在了工具類中,十分清晰,每句話幾乎都有注釋,每個(gè)類的創(chuàng)建時(shí)機(jī)、執(zhí)行對(duì)象都有明確的標(biāo)注。

github源代碼(解析)

https://github.com/wangwenzhen/Refresh-Object_C

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

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