透過 Diffable Data Source 輕鬆建立 table 內容

Zhi-Hong Lin
4 min readNov 1, 2021

--

在 iOS 13 前,需要調用 numberOfRowsInSectioncellForRowAt 方法來建立 data source。而要刷新資料,就要使用 performBatchUpdates()reloadData() 方法。

新的 UITableViewDiffableDataSource 抽象了大量的 UITableViewDataSource 邏輯, 我們可以透過 Snapshot 提供資料,以獲得 data source。新的刷新方法為apply(_ snapshot:),通過調用apply(_ snapshot:)不需要計算變更的indexPaths,也不需要調用 reload。

建立 UITableViewDiffableDataSource

UITableViewDiffableDataSource 有兩個 generic type,分別為 SectionIdentifierTypeItemIdentifierType代表 Sections 和 Items ,都必須遵循 Hashable 協議

宣告 Section identifier type

注:enum 本身就遵循 Hashable 協議,因此不需要另外 conform Hashable

宣告 Item identifier type

設置 data source instance

cellProvider 是個 closure,有三個參數,分別指向 tableView、indexPath、item 本身

宣告變數 dataSource 調用 makeDataSource()

private lazy var dataSource = makeDataSource()

assign 給 tableView.dataSource

tableView.dataSource = dataSource

如果想要使用其他的 data source 方法,如 titleForHeaderInSection()commit editingStyle: ,可以透過以下方式宣告一個子類別繼承 UITableViewDiffableDataSource

記得將 makeDataSource() 的回傳值改成上面定義的 DataSource

取得當前 Item

調用itemIdentifier(for:) 使用 indexPath 取得當前 Item

建立 NSDiffableDataSourceSnapshot

NSDiffableDataSourceSnapshot儲存 UITableViewDiffableDataSource 引用的 sections 和 items

  1. 建立 NSDiffableDataSourceSnapshot Instance,有兩個 generic type,必須跟 UITableViewDiffableDataSource 指定的 generic type 一樣
  2. apply(_:animatingDifferences:)設定顯示的內容,animatingDifferences 參數為數據更動時是否呈現動畫

最後即可在要刷新資料的地方調用add(with:)方法

多個 Section 對應不同的 Item Model

  • Section Enum 新增 case map
  • Item Enum 遵循 Hashable 協議,每個 case 對應不同的 Item Model

UITableViewDiffableDataSource的 ItemIdentifierType 改成上面宣告的 Item Enum

  • Snapshot 的 ItemIdentifierType 也改成上面宣告的 Item Enum
  • appendItems(_:toSection) 指定 Item 要對應哪個 Section

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

No responses yet

Write a response