網站首頁 編程語言 正文
引言
2022.02.11更新:新增了最簡單、高效和最推薦的方法。
2020.05.25更新:對總結進行了詳細的補充。
傳統的上拉加載更多
在iOS的開發過程中,如果用列表展示數據,此時一般的邏輯為上拉加載更多數據,配合MJRefresh就是在滑動到最底部時,觸發加載更多的網絡請求。
滑動過程中預加載
如果希望體驗好一點,那么可以在滑動的過程中,加入一個預加載機制,具體的做法如下:
方法1(最簡單、高效和最推薦):
使用MJRefresh
的特性(MJ大神已經替我們封裝好了,但是大多數人都不知道),在設置TableVIew的MJRefreshAutoFooter
時,triggerAutomaticallyRefreshPercent
這個屬性默認是1,我們來看看源代碼中是怎么說的:
此時我們只需要一行代碼:
MJRefreshAutoFooter *footer = [MJRefreshAutoFooter footerWithRefreshingTarget:weakSelf refreshingAction:@selector(loadMore)]; footer.triggerAutomaticallyRefreshPercent = -20; //關鍵的一行代碼 self.tableView.mj_footer = footer;
將這個屬性設置為一個負數,意思就是當控件的底部出現-20時就自動刷新,很明顯,-20的距離就代表還沒有滑動到底部,就觸發了刷新了,這樣便完成了我們的預加載的需求。
方法2(自己計算實現,不推薦了):
下滑(上拉)過程中,對當前scrollView(tableView)的剩余可滑動距離(總滑動距離占可滑動距離的)比例進行判斷,如果小于(大于)某個設定值,那么就觸發網絡請求(加載更多數據)。
- 這樣做的好處顯而易見,用戶不必再去多做一個上拉加載更多數據的操作了,如果我們需要展示的數據量非常大的話,那么此種加載方式可以節省用戶大量的操作時間,大大提升了用戶的使用體驗。
下面是具體實現細節(此細節是針對上述方法2的)
方法2是作者之前自己研究出來的,但是后來發現MJ已經為我們實現了這么好的方法,就用不到了。有興趣的同學可以看看方法2的具體實現:
1.我們需要在實現網絡請求的類中添加一個Bool屬性,用來判定當前是否正在進行網絡請求;
@property (nonatomic, assign) BOOL isLoadingDataBool; //是否正在請求數據
2.在scrollView的滑動代理方法中,處理預加載機制的邏輯
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { if (self.tableview.mj_footer.state == MJRefreshStateNoMoreData) { // 沒有更多數據,直接返回 return; } // 預加載的計算邏輯,當滑動距離>80%目前剩余可滑動距離的時候,觸發預加載 CGFloat threshold = 0.8; //設定的比例值 CGFloat current = scrollView.contentOffset.y + ((scrollView.contentSize.height != scrollView.frame.size.height) ? scrollView.frame.size.height : 0); //當前滑動距離 CGFloat total = scrollView.contentSize.height; //總的可滑動距離 CGFloat ratio = current / total; if (ratio >= threshold) { //滑動距離超過比例值 [self requestDataList:NO showHUD:NO]; //發起加載更多網絡請求 self.isLoadingDataBool = YES; //設置正在網絡請求狀態為YES(一定要寫在請求之后) } }
3.處理網絡請求
/// 發起網絡請求 /// @param isReloadBool 是否為刷新請求 /// @param isShowHUDBool 是否加載指示器 - (void)requestDataList:(BOOL)isReloadBool showHUD:(BOOL)isShowHUDBool { if (self.isLoadingDataBool) { // 當前正在請求,直接返回 return; } kWeakSelf(self); [DZCXHTTP requestWithResulted:^(BOOL isSuccessed, NSDictionary *dataDic, NSString *errorMsg) { kStrongSelf(self); strongself.isLoadingDataBool = NO; //請求完成,設置正在請求的狀態為NO }]; }
總結
這個預加載其實不難,但是有幾個細節的地方需要處理好:
1.第二步scrollView的代理方法中計算當前滑動時,一定要判斷當前的contenntSize是否等于scrollView的高度,如果等于的話證明scrollView是剛剛開始滑動,還沒有過一屏的距離,此時在計算當前滑動的距離時,就不能加上scrollView的高度;
2.當滑動的比例值超出我們設定值的時候,移動要先發起網絡請求,再設置正在網絡請求的狀態為YES,因為在網絡請求中會對該狀態進行判斷,如果為YES的話直接就return了;
3.在網絡請求的完成回調中,別忘記了將正在網絡請求的狀態改回為NO。
原文鏈接:https://www.jianshu.com/p/782ef1dc3e89
相關推薦
- 2022-08-29 Python通用驗證碼識別OCR庫ddddocr的安裝使用教程_python
- 2022-09-07 Jquery實現異步上傳文件_jquery
- 2023-04-07 C語言解決字符串中插入和刪除某段字符串問題_C 語言
- 2022-04-06 聊聊c++數組名稱和sizeof的問題_C 語言
- 2022-03-22 nginx中一個請求的count計數跟蹤淺析_nginx
- 2023-03-01 Golang?Makefile示例深入講解使用_Golang
- 2022-12-05 Flutter控制組件顯示和隱藏三種方式詳解_Android
- 2023-02-01 Python動態演示旋轉矩陣的作用詳解_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支