回頭看UITableView(三)-下拉刷新的實現(xiàn)

最近陷入了項目中一個日歷月視圖與周視圖切換效果的實現(xiàn),長時間沒有實現(xiàn)想要的效果弯蚜,沮喪至極孔轴。煩請有好想法的同學(xué)指點一二,在線等@留什么白碎捺。


結(jié)束例行的啰嗦路鹰,進(jìn)入正題。

大家可能都用過MJRefresh,十分之方便收厨,李明杰老師借助runtime的特性晋柱,極盡之能,讓千千萬萬小白開發(fā)者和遵循不重復(fù)制造輪子原則的開發(fā)者用最少的代碼就實現(xiàn)了界面下拉刷新的功能诵叁。我們今天不談runtime的黑魔法雁竞,而是UITableView最常見的刷新數(shù)據(jù)方式下拉刷新的實現(xiàn)過程。

首先黎休,我們定義三個枚舉值

typedef NS_ENUM(NSUInteger, RefreshState) {
    RefreshStateNormal,//正常
    RefreshStatePulling,//釋放即可刷新
    RefreshStateLoading,//加載中
};

分別表示正常狀態(tài)浓领、釋放即可刷新狀態(tài)玉凯、加載中狀態(tài)

為了簡單說明,我們只用一個UILabel來表現(xiàn)就可以联贩,把它放在內(nèi)容上方漫仆,也就是正常情況下看不到的地方,只有下拉的時候才能看到泪幌。

UILabel的位置

然后我們估算一個大體的距離盲厌,從而確定觸發(fā)加載狀態(tài)的臨界點。

簡單描述一下將要實現(xiàn)的情形:

我們往下滑動視圖祸泪,如果視圖下滑到觸發(fā)點吗浩,狀態(tài)變?yōu)?code>RefreshStatePulling,即標(biāo)簽文字變?yōu)椤八墒旨纯伤⑿隆薄?br> 接下來有兩種狀況會發(fā)生:一,松開手没隘;二懂扼,不松手,又向初始位置滑右蒲。第一種情況阀湿,當(dāng)你松開手時,因為UIScrollView有回彈效果瑰妄,視圖會往上滑動陷嘴,當(dāng)?shù)竭_(dá)觸發(fā)點時,狀態(tài)改為RefreshStateLoading,即視圖停在當(dāng)前位置间坐,不受回彈作用影響灾挨,標(biāo)簽文字變?yōu)椤凹虞d中...”,等加載動作完成之后,手動觸發(fā)復(fù)原動作竹宋,視圖滑到原始狀態(tài) RefreshStateNormal,同時標(biāo)簽文字變?yōu)椤吕⑿隆统危坏诙N情況,你沒有松手蜈七,然后又往回滑動浴骂,當(dāng)?shù)竭_(dá)觸發(fā)點以上時,狀態(tài)變?yōu)槌跏紶顟B(tài)RefreshStateNormal宪潮。

如果你對上述過程不是很了解的話溯警,那你隨便找個帶下拉刷新的應(yīng)用試試就行了,不用溫柔狡相,越暴力越好梯轻。弄清上述過程是實現(xiàn)整個流程的基礎(chǔ)。

接下來要做的就是決定什么時候改變狀態(tài)了尽棕,參照上述過程喳挑,我們在UIScrollView的代理函數(shù)scrollViewDidScroll:監(jiān)控contentOffset的變化,再結(jié)合isDragging屬性就可以改變狀態(tài)了。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    if(scrollView.contentOffset.y < -SwitchPoint-self.originalInsetTop){
        if(self.refreshState == RefreshStateNormal){//小于臨界值(在觸發(fā)點以下)伊诵,如果狀態(tài)是正常就轉(zhuǎn)為下拉刷新单绑,如果正在刷新或者已經(jīng)是下拉刷新則不變
            self.refreshState = RefreshStatePulling;
        }
    }else{//大于臨界值(在觸發(fā)點以上,包括觸發(fā)點)
        if(scrollView.isDragging){//手指沒有離開屏幕
            if(self.refreshState == RefreshStatePulling){//原來是下拉的話變成正常曹宴,原來是刷新或者正常的話不變
                self.refreshState = RefreshStateNormal;
            }
        }else{//手指離開屏幕
            if(self.refreshState == RefreshStatePulling){//原來是下拉的話變成加載中搂橙,原來是加載中或者正常的話不變
                self.tableView.contentInset = UIEdgeInsetsMake(self.originalInsetTop+SwitchPoint, 0, 0, 0);//改變contentInset的值就可以取消回彈效果停留在當(dāng)前位置了 關(guān)于contentIinset的介紹,可以查看我的上一篇文章
                self.refreshState = RefreshStateLoading;
            }
        }
    }    
}

這段代碼決定了UIScrollView每個時刻的狀態(tài)笛坦,那么接下來的就簡單多了区转,只要重寫一下setRefreshState:方法就可以了。

- (void)setRefreshState:(RefreshState)refreshState{
    _refreshState = refreshState;
    switch (refreshState) {
        case RefreshStateNormal:
            self.pulldownLabel.text = @"下拉刷新";
            [self.pulldownLabel sizeToFit];
            break;
        case RefreshStateLoading:
            self.pulldownLabel.text = @"正在刷新...";
            [self.pulldownLabel sizeToFit];
            if(self.refreshBlock){
                self.refreshBlock();//這里就是你要執(zhí)行的耗時的操作
            }            
            break;
        case RefreshStatePulling:
            self.pulldownLabel.text = @"松開即可刷新";
            [self.pulldownLabel sizeToFit];
            break;
        default:
            break;
    }
}

看一下我們的效果:


平凡而簡單的效果

當(dāng)然你會說這不夠diao,不夠炫酷版扩,人家的效果都是這樣:

又被你發(fā)現(xiàn)了废离,??,我滿(hao)是(wu)虔(jie)誠(cao)地盜了大神的圖礁芦,@M了個J蜻韭,大神,膝蓋已發(fā)貨柿扣,請驗收湘捎。

那么我們怎么實現(xiàn)這樣的效果呢,很簡單窄刘,在上邊設(shè)置狀態(tài)的代碼里添加動畫就行了。來一段偽的代碼:

case RefreshStateNormal:
     self.pulldownLabel.text = @"下拉刷新";
     [UIView animateWithDuration:0.3 animations:^{
         self.arrowImage.transform = CGAffineTransformMakeRotation(M_PI/2);//箭頭旋轉(zhuǎn)180o
     }];
     break;

還有一點需要強(qiáng)調(diào)舷胜,在scrollViewDidScroll:里保持加載狀態(tài)時修改了contentInset,所以取消加載狀態(tài)恢復(fù)原狀時只需...如此如此:
- (void)endRefresh{
if(self.refreshState == RefreshStateLoading){
self.refreshState = RefreshStateNormal;
[UIView animateWithDuration:0.3 animations:^{
self.tableView.contentInset = UIEdgeInsetsMake(self.originalInsetTop, 0, 0, 0);
} completion:nil];
}
}

OK娩践,希望看到這里你能理解下拉刷新的整個過程及原理了,歡迎指正和打擊烹骨。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末翻伺,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子沮焕,更是在濱河造成了極大的恐慌吨岭,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件峦树,死亡現(xiàn)場離奇詭異辣辫,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)魁巩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門急灭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谷遂,你說我怎么就攤上這事葬馋。” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵畴嘶,是天一觀的道長蛋逾。 經(jīng)常有香客問我,道長窗悯,這世上最難降的妖魔是什么区匣? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任骡楼,我火速辦了婚禮工秩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘欠窒。我一直安慰自己悦污,他們只是感情好铸屉,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著切端,像睡著了一般彻坛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上踏枣,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天昌屉,我揣著相機(jī)與錄音,去河邊找鬼茵瀑。 笑死间驮,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的马昨。 我是一名探鬼主播竞帽,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鸿捧!你這毒婦竟也來了屹篓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤匙奴,失蹤者是張志新(化名)和其女友劉穎堆巧,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體泼菌,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡谍肤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了哗伯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谣沸。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖笋颤,靈堂內(nèi)的尸體忽然破棺而出乳附,到底是詐尸還是另有隱情内地,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布赋除,位于F島的核電站阱缓,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏举农。R本人自食惡果不足惜荆针,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望颁糟。 院中可真熱鬧航背,春花似錦、人聲如沸棱貌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽婚脱。三九已至今魔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間障贸,已是汗流浹背错森。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留篮洁,地道東北人涩维。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像袁波,于是被迫代替她去往敵國和親瓦阐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫锋叨、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,103評論 4 62
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,116評論 25 707
  • 放松是一種慈悲宛篇,對人不苛求娃磺,對已不苛責(zé)。 今天的領(lǐng)航叫倍,明顯更放松了些偷卧,開始可以跟隨分享著的故事和情緒,可...
    山間竹音閱讀 155評論 0 0
  • 網(wǎng)咖行業(yè)是由網(wǎng)吧演變過來的晌梨,參考前瞻 產(chǎn)業(yè)研究院《2016-2021年中國網(wǎng)吧行業(yè)市場前瞻與投資戰(zhàn)略規(guī)劃分析報告》...
    崇拜_e716閱讀 476評論 0 1
  • 工作桥嗤,不同于生活。 生活仔蝌,其實也是工作泛领。 22歲之前,我的生活是上學(xué)敛惊。 22歲之后渊鞋,我的生活有工作。 學(xué)習(xí)是輕松的...
    零蘭閱讀 156評論 0 2