iOS-UITableView你需要掌握的屬性
背景
- 在現今的開發中,UITableView和UICollectionView算是最最流行的控制元件了,基本上每一個應用內部都會多次使用到這類控制元件,它們統一都繼承自UIScrollView
- 平時我們都會用它們來展示資料,但是也有很多情況,比如頁面上下拖動的時候導航欄透明度改變、一個工具欄在頁面向上拖動到一定程度後懸浮到一個位置不動了、再比如簡書的個人頁面,頭像在導航欄上,頭像會隨著頁面的上下拖動變大變小、再比如上拉下拉重新整理的實現、再比如點選狀態列,tabbleView如果不是在最頂部,那麼它會立即滾動到頁面最頂部等等等等,這些效果全部都是通過UIScrollView的一些屬性實現的
- 而且這類控制元件也算是我們開發中最基本的控制元件了,基本我們天天都需要和它們打交道,所以說,掌握它們的使用不僅僅是對我們最基本的要求,也可以讓我們實現很多效果,但是這些都需要建立在對它們一些易混淆屬性理解的基礎之上
- 本文將以UITableView為例說明下它的一些關鍵屬性,並結合一些屬性簡單實現下拉重新整理
- 先來看下這篇文章最後結合相關屬性講解的一個小Demo效果
![313229-f151c96cfe1feb30.gif](https://i.iter01.com/images/adf36f012b38de4bbc4924018eb7d901b131641fed4fbe0e156dd02faba7118c.gif)
refresh.gif
知識點
1)contenSize -- 滾動檢視內容的尺寸
- 這個屬性是CGSize型別的,它決定了你的滾動檢視是否能滾動,能夠滾動多遠
- 這個屬性對於實現我們本文要講解的下拉重新整理是至關重要的,我們需要明確contenSize包含了tabbleview的什麼內容,也就是什麼內容才算是contenSize的一部分
- 除了UITableviewCell屬於contenSize的一部分之外,tabbleview的頭部和尾部檢視也算是它的contenSize的一部分
- 如果設定了內邊距,那麼內邊距是不算contenSize的一部分的
- 如果給tabbleview新增子控制元件,這個子控制元件也不屬於contenSize的一部分
- 而且給scrollview內部子控制元件新增約束時,最頭疼的其實就是這個contenSize,它的contenSize需要根據子控制元件的尺寸以及子控制元件與scrollview之間的間距計算
![313229-4dc7366bb227ca33.png](https://i.iter01.com/images/8d59c47b21b613e0f17ba67485b8b71e83acade6c2cb6b9941134063b57c165e.png)
偏移量.png
2)contentOffset -- 偏移量
- 是一個CGPoint型別的屬性,一般而言,上下滑動,我們需要它的contentOffset.y,左右滑動我們需要它的contentOffset.x
- 這是一個滾動檢視最最基本的屬性,也是最重要的屬性,基本上,上述所有效果都是基於它來實現的
- 當tabbleview是在一個導航條下面的話,那麼系統會自動將tabbleview內容增加64的頂部內邊距,因此它的偏移量y值預設是-64
- 我們可以這樣去理解它,以一個上下滾動的tabbleview為例,
contentOffset.y = tabbleview的frame的左上角的y值 - tabbleview的內容的左上角的y值
,而且這個座標系以tabbleview的內容的左上角為座標原點
![313229-0773c77b82c510bf.png](https://i.iter01.com/images/da6aa0245afe4bb5154dc04dd265743c913e548b5d120945f048ba2cb54e34e2.png)
座標系.png
3)showsHorizontalScrollIndicator和showsVerticalScrollIndicator
- 是BOOL型別的,決定了是否隱藏水平或者垂直方法滾動條,之所以提及這2個屬性是要說一個注意點,比如我們在使用scrollview時,如果我們需要遍歷scrollview的子控制元件陣列,我們就需要注意這2個控制元件,它也算scrollview的子控制元件
4)scrollsToTop
- 一個BOOL型別的屬性,可以控制點選狀態列,是否讓不在頂部的滾動檢視回到最頂部
- 屬性預設為YES,也就是系統預設幫我們實現了這個效果
- 需要說明的是如果頁面有2個及以上滾動檢視的時候,你需要控制哪一個滾動檢視支援scrollsToTop,哪些不支援
5)estimatedHeight --- 估算高度
這裡針對tabbleview說一下這個屬性,因為tabbleview不需要我們自己計算contensize,所以預設情況下,tabbleview都是先呼叫heightForRow方法然後再去呼叫cellForRow方法,而且heightForRow會根據當前tabbleview有多少行就去呼叫多少次,無論是否cell當前被展示
如果我們給了tabbleview一個估算高度,那麼它可以減少heightForRow方法的呼叫頻率,延遲計算目前不需要展示cell的高度,需要展示再去計算,這個也算是這個屬性的優點
它也是有一定缺點的,既然是估算高度,那我們給多少算合適的,其實給多給少都不太好,給少了,它呼叫heightForRow方法就會多,給少了,雖然呼叫heightForRow方法少,但是tabbleview計算它的contensize的誤差就越大,明顯效果就是滾動條的高度很奇怪(跳躍性很大),所以還是根據cell平均值給一個估算高度
6)cellForRowAtIndexPath和indexPathForSelectedRow
-
cellForRowAtIndexPath
這個方法根據傳入的indexPath可以獲得顯示在tableView上的某一行cell -
indexPathForSelectedRow
這個方法可以在系統沒有傳入indexPath的方法或者自定義的方法中,通過該方法獲得被選中的cell的indexPath,可以得到section,row,也是非常實用的
利用偏移量簡單實現一下下拉重新整理(仿新浪微博)
- 其實一開始說的那些效果實現起來都是不難的,主要是我們需要對這些基本且關鍵屬性非常理解,知己知彼,百戰不殆嘛
- 下面的這些程式碼主要是關於下拉過程中,更新下拉重新整理控制元件文字以及箭頭狀態的描述,關於傳送網路請求,這裡只是模擬一下傳送,新新增的資料也是假資料
- 關於下拉重新整理控制元件是否作為tabbleview的頭部檢視,這個我是建議不要這樣做的,因為頭部檢視一般最好是用來作為輪播器或者廣告使用,我們一般最好把重新整理控制元件使用addSubview的方法新增到tabbleview上面最好
![313229-c5b2d77462518c62.png](https://i.iter01.com/images/65d4f8c64e848783c05e18076438692ae58be74e80cd092825d3892fb58c2b44.png)
下拉重新整理.png
/**
* 停止拖拽,需要在這個方法裡面監聽停止拖拽的時候偏移量,根據偏移量判斷重新整理控制元件是否完全顯示,是的話進入重新整理,不是的話直接返回
*/
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
// 如果正在重新整理, 直接返回
if (self.isHeaderRefreshing) return;
// 當偏移量 <= offsetY時(注意正負值), 重新整理控制元件就完全出現了
CGFloat offsetY = - (self.tableView.contentInset.top + self.headerBtn.lb_height);
[self.loadingView stopAnimating];
self.headerBtn.imageView.hidden = NO;
if (self.tableView.contentOffset.y <= offsetY) { // 重新整理header完全出現了
// 進入重新整理狀態
[self headerBeginRefresh];
}
}
- 還需要在
scrollViewDidScroll
方法中實時根據偏移量控制下拉重新整理控制元件文字以及箭頭的狀態,這個監控狀態的程式碼這裡不貼出來了,放在程式碼裡面有,註釋也是很詳細的 - 開始重新整理方法實現
#pragma mark - 開始重新整理
- (void)headerBeginRefresh
{
//如果當前正在重新整理,那麼不往下繼續執行
if (self.isHeaderRefreshing) return;
//否則,進入重新整理狀態
self.headerRefreshing = YES;
//顯示菊花
self.loadingView.alpha = 1.0;
[self.loadingView startAnimating];
[self.headerBtn setTitle:@"載入中..." forState:UIControlStateNormal];
self.headerBtn.imageView.transform = CGAffineTransformIdentity;
self.headerBtn.imageView.hidden = YES;
// 顯示載入中...,這個時候這個重新整理控制元件是會自己懸浮在導航欄下面,不需要人為拽著不鬆手
//這個效果,我們可以通過增大tabbleview的內邊距來達到這個效果
[UIView animateWithDuration:0.25f animations:^{
//因為重新整理控制元件的y值就是-50,它自己高度也是50,所以只需要讓tabbleview內邊距向下走50,那麼重新整理控制元件就會完全顯示了
UIEdgeInsets inset = self.tableView.contentInset;
inset.top += self.headerBtn.lb_height;
self.tableView.contentInset = inset;
}];
//由於是模擬傳送網路請求,所以延遲1.5秒後再去載入資料
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 傳送請求給伺服器
[self loadNewData];
});
}
- 結束重新整理方法實現
#pragma mark - 結束重新整理
- (void)headerEndRefresh
{
self.headerRefreshing = NO;
self.headerBtn.hidden = YES;
// 減小內邊距
// 重新整理已經停止,不需要重新整理控制元件顯示在使用者能看到的範圍,所以需要減少tabbleview的內邊距
[UIView animateWithDuration:0.25 animations:^{
UIEdgeInsets inset = self.tableView.contentInset;
inset.top -= self.headerBtn.lb_height;
self.tableView.contentInset = inset;
}completion:^(BOOL finished) {//重新整理控制元件縮回到使用者看不到的位置後,更新重新整理控制元件以及內部子控制元件的狀態
self.headerBtn.hidden = NO;
self.loadingView.alpha = 0.0;
[self.loadingView stopAnimating];
}];
}
ok,效果實現基本結束了,感謝您的閱讀,不足之處歡迎指正
點選檢視程式碼實現
相關文章
- 皇御貴金屬:貴金屬投資需要掌握哪些技巧
- [譯] 關於 SPA,你需要掌握的 4 層
- 2021年你需要掌握的前端小知識前端
- 課時26.a標籤其它屬性(掌握)
- 你有所不知的margin屬性
- [譯] 關於 SPA,你需要掌握的 4 層 (2)
- 幾你需要熟練掌握的辦公軟體
- 說下你對cursor屬性的理解
- 掌握了開源框架還不夠,你更需要掌握原始碼框架原始碼
- 10個你在JavaScript面試前需要掌握的概念JavaScript面試
- HTML 屬性你都懂了嗎HTML
- selenium用XPATH直接獲取屬性值 需要使用.get_attribute(“屬性名”)
- 初學Web前端開發,你需要掌握的11項技能Web前端
- 碼教授告訴你SEM最佳化師需要掌握的技巧
- 你瞭解HTML5的download屬性嗎?HTML
- Python 類的屬性與例項屬性Python
- 有關Kotlin屬性代理你需要知道的一切Kotlin
- CMake 屬性之全域性屬性
- 在 2021 年你需要掌握的 7 種關於 JavaScript 的陣列方法JavaScript陣列
- 如何在坑中掌握模型屬性 $casts 和 $appends 的正確使用姿勢模型ASTAPP
- 帶你深入理解Android中的自定義屬性!!!Android
- defer 屬性和 async 屬性
- logback 的屬性
- 【超詳細】Linux常用命令,這些你需要掌握!Linux
- 讓PyTorch訓練速度更快,你需要掌握這17種方法PyTorch
- 測試開發:你所需要掌握瞭解的效能測試知識
- CSS 屬性篇(七):Display屬性CSS
- CMake 屬性之目錄屬性
- CMake 屬性之目標屬性
- 舉例說說你對white-space屬性的理解
- 你不知道的下劃線屬性-text-decoration
- 面試需要掌握的知識點面試
- 關於mybatis,需要掌握的基礎MyBatis
- JavaScript物件的資料屬性與訪問器屬性JavaScript物件
- Swift 中的屬性Swift
- Object物件的屬性Object物件
- 檔案的屬性
- Cookie 的 SameSite 屬性Cookie
- GObject的物件屬性GoObject物件