使用 UITableViewController

Thomas Mak wrote at 2021-04-18.

#ios

要使用 UITableViewController,必須了解其 Delegate Protocol:UITableViewDelegateUITableViewSource

UITableView 的構建及顯示(Rendering)是系統負責的,這樣可以確保 UITableView 的渲染符合 iOS 的速度要求。

UITableView 可以自動在用戶滑動(Scroll)時將 UITableViewCell 重用,當那個格(Cell)被滑出畫面時,便會被放入重用列表(Reuse Queue),再有需要時,便會被拿來重用,按新顯示需求的資訊而重新準備好,然後再呈現出來。

這個就是 UITableView 的重用機制,這樣可以確保無論有多少數據要顯示,UITableViewCell 數量都可以控制在有限數目。

因為相對於數據(Data),UIView 會較為佔用記憶體,而且不斷 Allocate 開新及移除 View ,也是耗時較多的操作,所以將最耗時的操作重用,便可以有效提升效率。

同時,由於 UITableView 的製作都是由系統負責才做到如此高效,所以開發時便需要為這個專門的系統而有獨特的 API 設計,這就是 UITableViewDelegate 及 UITableViewDataSource 的由來。


那麼 Delegate 和 DataSource 有什麼分別?

DataSource 是連接 UITableView 及數據的專用 Protocol。

內有最重要的 3 個函數:

  • Number of sections
  • Number of rows in section
  • Cell for Table View at Index Path

通過解答此三個問題,iOS便懂得如何製作及顯示我們的 UITableView。第一個問題,預設答案是 1 個Section。Section 即是分類,例如將聯絡列表分開成 A-Z 26 個分類等。第二個問題,會因應有多少個 Section 便會問我們多少次,逐個逐個 Section 問我們這個分組內有多少個Row。

話說,這個返回數字不須要 Hard Code。可以因應情況改變,例如如果列出Profile 時,有分 VIP 及 非 VIP 兩種帳號,則有可能他們顯示的 Profile 個人帳號資料列表有不同的 Row 行數。


Cell for Table View at Index Path

至於第三個問題,

IndexPath 是記錄低哪個 Section 哪個 Row,

所以這個函數就是在問某一個 Section 某一個 Row 的那個介面,在 UITableView 中,一行的介面是 UITableViewCell。

為何我說某一?因為系統會自動處理整個列表的顯示,所以,如果用戶滑動列表到途中某位置時,系統便會突然需要某一個的資料及如何顯示的介面設定。 要用好這個函數,可以分為兩個階段:

  1. ReuseIdentifier
  2. 準備要 Return 的 Cell

ReuseIdentifier

一個基本的 UITableView,只需要一個 reuse identifier,意即只有一種類的 UITableViewCell。

但當 Table 變得複雜後,我們便有需要多於一種 Identifier,以設定 App 為例,當中有的 Cell 只是 Icon 及文字,有的 Cell是有 > 符號,有的則有個 UISwitch 在右方,有的則有 Checkmark。這樣一數,就有 4 種不同的 UITableViewCell,那麼我們須要 4 種 reuse identifier 嗎?可以,但不必要。

一個 reuse identifier 代表一個重用列表(Reuse Queue),要設定獨立重用列表的主要原因,是涉及有不同的 Layout 界面排版或有不同的 UIView 介面在內。例如,有 UISwitch 的,可以自成一個重用列表,有 UIImage Icon 的也可以。至於其他文字加一個右方標記,可以共用一個重用列表。

所以在這個 cellForTableViewAtIndexPath 函數中,第一步是需要按所提供 IndexPath 的 Section 及 Row,決定要使用哪一個 ReuseIdentifier (假設我們已經分析知道自己的列表類型分類)


準備 Cell Return

拿出可以重用的 UITableViewCell 後,我們就要因應這個 Section 這個 Row 須要的界面,換上內容及設定好當中倘有的 UIView。

例如 UISwitch 的,我們便要按數據設定這個 Switch 是 On 還是Off。另外還要替換文字。

如果是右邊有 Checkmark 或 > 號等 Accessory的,也要一併準備好。 準備好後,便可以把這個 UITableViewCell return 給 iOS 系統了。 所以,如果這個準備過程中,你發現程序中不只有簡單的文字替換及UIView 設定,而是有新增或移除 UIView,那麼便很有可能這個 Cell 需要一個獨立的重用列表(Reuse Queue)了。


UITableViewAccessory

預設的 UITableViewCell 右方有個 Accessory,這個位置預設有 4 種方式:

  • Checkmark
  • Disclosure Indicator
  • Info button
  • Disclosure Info Button

Checkmark 通常用於選擇,例如設定 App 內,Safari 的搜尋器選擇,不同 Row 右方要麼是 Checkmark,要麼是 None。這樣就可以令到一個多選也能繼承 UITableView 的彈性。例如 Header View 可以加入額外的文字描述,每個 Row除了用文字,亦可以利用Subtitle 加入輔助描述文字。至於是單選還是多選,就要視乎我們的 ViewController 邏輯是如何處理了。

至於 > Disclosure Indicator,用法則較為明顯,就是代表按下後可以跳入下一層,剛剛的 Setting 設定 App,在臨進入 Safari 時,其 Indicator 就是一個 > 符號,代表按下後將會進入下一層。

所以 UINavigationController 和 UITableViewController 常常是放在一起使用的。

Info button 及 Disclosure info button 則較為特別,其 Info 是獨立為一個 UIButton。通常按下後會是和這一行 Item 有關的資訊。例如設定。

以 1-to-many 的列表為例,例如列出不同 Projects 項目,當中亦有不同的 Task 待辦事項列表,正常按下項目後,會彈出下一版的列表顯示其待辦事項。

而 Info Button 就可以充當另一按鈕,於按下後打開項目的設定頁而不是打開其列表,通常會使用 present 來由下向上滑出,以代表這個畫面和原有的 Navigation Controller 是不同一個層級的。

Comments

no comments yet.