iOS開發(fā)TableView網(wǎng)絡(luò)請求及展示預(yù)加載實現(xiàn)示例
引言
2022.02.11更新:新增了最簡單、高效和最推薦的方法。
2020.05.25更新:對總結(jié)進行了詳細的補充。
傳統(tǒng)的上拉加載更多
在iOS的開發(fā)過程中,如果用列表展示數(shù)據(jù),此時一般的邏輯為上拉加載更多數(shù)據(jù),配合MJRefresh就是在滑動到最底部時,觸發(fā)加載更多的網(wǎng)絡(luò)請求。
滑動過程中預(yù)加載
如果希望體驗好一點,那么可以在滑動的過程中,加入一個預(yù)加載機制,具體的做法如下:
方法1(最簡單、高效和最推薦):
使用MJRefresh
的特性(MJ大神已經(jīng)替我們封裝好了,但是大多數(shù)人都不知道),在設(shè)置TableVIew的MJRefreshAutoFooter
時,triggerAutomaticallyRefreshPercent
這個屬性默認是1,我們來看看源代碼中是怎么說的:
此時我們只需要一行代碼:
MJRefreshAutoFooter *footer = [MJRefreshAutoFooter footerWithRefreshingTarget:weakSelf refreshingAction:@selector(loadMore)]; footer.triggerAutomaticallyRefreshPercent = -20; //關(guān)鍵的一行代碼 self.tableView.mj_footer = footer;
將這個屬性設(shè)置為一個負數(shù),意思就是當(dāng)控件的底部出現(xiàn)-20時就自動刷新,很明顯,-20的距離就代表還沒有滑動到底部,就觸發(fā)了刷新了,這樣便完成了我們的預(yù)加載的需求。
方法2(自己計算實現(xiàn),不推薦了):
下滑(上拉)過程中,對當(dāng)前scrollView(tableView)的剩余可滑動距離(總滑動距離占可滑動距離的)比例進行判斷,如果小于(大于)某個設(shè)定值,那么就觸發(fā)網(wǎng)絡(luò)請求(加載更多數(shù)據(jù))。
- 這樣做的好處顯而易見,用戶不必再去多做一個上拉加載更多數(shù)據(jù)的操作了,如果我們需要展示的數(shù)據(jù)量非常大的話,那么此種加載方式可以節(jié)省用戶大量的操作時間,大大提升了用戶的使用體驗。
下面是具體實現(xiàn)細節(jié)(此細節(jié)是針對上述方法2的)
方法2是作者之前自己研究出來的,但是后來發(fā)現(xiàn)MJ已經(jīng)為我們實現(xiàn)了這么好的方法,就用不到了。有興趣的同學(xué)可以看看方法2的具體實現(xiàn):
1.我們需要在實現(xiàn)網(wǎng)絡(luò)請求的類中添加一個Bool屬性,用來判定當(dāng)前是否正在進行網(wǎng)絡(luò)請求;
@property (nonatomic, assign) BOOL isLoadingDataBool; //是否正在請求數(shù)據(jù)
2.在scrollView的滑動代理方法中,處理預(yù)加載機制的邏輯
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { if (self.tableview.mj_footer.state == MJRefreshStateNoMoreData) { // 沒有更多數(shù)據(jù),直接返回 return; } // 預(yù)加載的計算邏輯,當(dāng)滑動距離>80%目前剩余可滑動距離的時候,觸發(fā)預(yù)加載 CGFloat threshold = 0.8; //設(shè)定的比例值 CGFloat current = scrollView.contentOffset.y + ((scrollView.contentSize.height != scrollView.frame.size.height) ? scrollView.frame.size.height : 0); //當(dāng)前滑動距離 CGFloat total = scrollView.contentSize.height; //總的可滑動距離 CGFloat ratio = current / total; if (ratio >= threshold) { //滑動距離超過比例值 [self requestDataList:NO showHUD:NO]; //發(fā)起加載更多網(wǎng)絡(luò)請求 self.isLoadingDataBool = YES; //設(shè)置正在網(wǎng)絡(luò)請求狀態(tài)為YES(一定要寫在請求之后) } }
3.處理網(wǎng)絡(luò)請求
/// 發(fā)起網(wǎng)絡(luò)請求 /// @param isReloadBool 是否為刷新請求 /// @param isShowHUDBool 是否加載指示器 - (void)requestDataList:(BOOL)isReloadBool showHUD:(BOOL)isShowHUDBool { if (self.isLoadingDataBool) { // 當(dāng)前正在請求,直接返回 return; } kWeakSelf(self); [DZCXHTTP requestWithResulted:^(BOOL isSuccessed, NSDictionary *dataDic, NSString *errorMsg) { kStrongSelf(self); strongself.isLoadingDataBool = NO; //請求完成,設(shè)置正在請求的狀態(tài)為NO }]; }
總結(jié)
這個預(yù)加載其實不難,但是有幾個細節(jié)的地方需要處理好:
1.第二步scrollView的代理方法中計算當(dāng)前滑動時,一定要判斷當(dāng)前的contenntSize是否等于scrollView的高度,如果等于的話證明scrollView是剛剛開始滑動,還沒有過一屏的距離,此時在計算當(dāng)前滑動的距離時,就不能加上scrollView的高度;
2.當(dāng)滑動的比例值超出我們設(shè)定值的時候,移動要先發(fā)起網(wǎng)絡(luò)請求,再設(shè)置正在網(wǎng)絡(luò)請求的狀態(tài)為YES,因為在網(wǎng)絡(luò)請求中會對該狀態(tài)進行判斷,如果為YES的話直接就return了;
3.在網(wǎng)絡(luò)請求的完成回調(diào)中,別忘記了將正在網(wǎng)絡(luò)請求的狀態(tài)改回為NO。
以上就是iOS開發(fā)TableView網(wǎng)絡(luò)請求及展示預(yù)加載實現(xiàn)示例的詳細內(nèi)容,更多關(guān)于iOS TableView網(wǎng)絡(luò)請求預(yù)加載的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
淺談iOS 關(guān)于小數(shù)精確計算(NSDecimalNumber)
本篇文章主要介紹了淺談iOS 關(guān)于小數(shù)精確計算(NSDecimalNumber),具有一定的參考價值,有興趣的可以了解一下2017-08-08iOS開發(fā)中實現(xiàn)郵件和短信發(fā)送的簡單示例
這篇文章主要介紹了iOS開發(fā)中實現(xiàn)郵件和短信發(fā)送的簡單示例,編程語言依然是傳統(tǒng)的Objective-C,需要的朋友可以參考下2015-09-09iOS 11 UINavigationItem 去除左右間隙的方法
本篇文章主要介紹了iOS 11 UINavigationItem 去除左右間隙的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10詳解iOS開發(fā)中Keychain的相關(guān)使用
這篇文章主要介紹了iOS開發(fā)中Keychain的相關(guān)使用,文中列舉了一個使用Keychain來保存密碼的例子,需要的朋友可以參考下2015-10-10iOS內(nèi)存管理中引用計數(shù)的學(xué)習(xí)
文章給大家分享了關(guān)于iOS內(nèi)存管理中引用計數(shù)的相關(guān)知識點,對此有需要的朋友可以跟著學(xué)習(xí)下。2018-05-05