34.%d\n Xcode — UITableViewDiffableDataSource<Section, Item>(ㄧ)

春麗 S.T.E.M.
7 min readDec 15, 2021

--

在製作tableView時,如果有各種客製化cell,那麼管理dataSource就是個問題,不過在iOS13以後,我們有UITableViewDiffableDataSource可以幫忙,它將Section與Item分開,Section就是表格的區塊,Item就是區塊內的row。

這個簡單的APP就是用這種方式做出來的,透過右方的navBarItem,將資料加入tableView,透過滑動表格的欄位(row),在按下刪除時去更新dataSource,於是重新顯示表格資料,而不是使用reloadData去更新表格。

這個更新dataSource的方式,是透過NSDiffableDataSourceSnapshot,改動資料,重新塞入資料。

此外,並沒有透過storyboard去產生VC,而是透過程式碼,那麼便要在SceneDelegate透過顯示視窗,設定視窗的root,因為要有navBarItem,所以這個root就是新建立的navigationController。

還有在加入cell的資料時,隨機產生textColor,而這種加入dataSource的方式,要注意Item是hashable,所以必須去比對要新加入的資料與早先加入的資料有沒有重複,如果重複就return。

而iOS13在滑動刪除表格有新的方式可以做,以下是舊作法:

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let action = UITableViewRowAction(style: .default, title: "刪除") { ac, index in
self.tripSet.remove(at: index.row)
self.updateDataSource()
}
return [action]
}

透過tableView的rowAction去更改資料,再重新顯示。然而,這個作法寫完後,雖然可以成功顯示,卻出現如下訊息:

新的建構方式

設定tableView cell左滑或右滑出現動作的trailingSwipe / leadingSwipe,像這樣:

接著,我們可以簡單對表格做出移動與排列,但這必須要先進入編輯模式,所以我們可以這樣寫

override func viewDidLoad() {let rightBar = UIBarButtonItem(barButtonSystemItem: .organize, target: self, action: #selector(buttonTapped))
navigationItem.rightBarButtonItem = rightBar
}

@objc func buttonTapped() {
myTableView.setEditing(!myTableView.isEditing, animated: true)
}

加入rightBarButtonItem,並且點擊動作為,如果非編輯模式就不設定編輯這樣一句像是廢話的描述,哈。

剩下則是moveRowAt、editingStyle了,moveRowAt的概念是,我必須要從原來的資料集合去移除sourceIndexPath.row的這個資料,接著放到destinationIndexPath.row去,總之是很好玩。

以下reference

最後附上

--

--

春麗 S.T.E.M.
春麗 S.T.E.M.

Written by 春麗 S.T.E.M.

Do not go gentle into that good night, Old age should burn and rave at close of day; Rage, rage, against the dying of the light.

No responses yet