By adding the built in editButton to the rightBarButtonItem we get some built in Edit Done button transformations which automatically call setEditing for us which in turn enables us to put the UITableView
into edit mode.
func setupViews() {
navigationItem.title = "Classic Arcade"
navigationItem.rightBarButtonItem = editButtonItem // magic!
view = tableView
}
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
tableView.setEditing(editing, animated: animated)
}
We can then react to the style of the cell row returned (.delete
by default).
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
games.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
addGame("Ms Pacman")
}
}
If we want to insert we need to override the default .delete
editting style and return an .insert
one.
// To trigger single action insert mode.
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .insert
}
Which can then in turn insert a row.
private func addGame(_ game: String) {
games.append(game)
let indexPath = IndexPath(row: games.count - 1, section: 0)
tableView.beginUpdates()
tableView.insertRows(at: [indexPath], with: .fade)
tableView.endUpdates()
}
To make cells swipeable, return a collection of swipe actions for either the trailing or leading side.
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .destructive, title: "Delete", handler: { (action, view, completionHandler) in
self.games.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
})
action.image = makeSymbolImage(systemName: "trash")
let configuration = UISwipeActionsConfiguration(actions: [action])
return configuration
}
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .normal, title: "Document", handler: { (action, view, completionHandler) in
// Do something with documents...
})
action.image = makeSymbolImage(systemName: "paperclip")
let configuration = UISwipeActionsConfiguration(actions: [action])
return configuration
}
You can either do an add on the view itself.
@objc
func addButtonPressed() {
guard let text = textField.text else { return }
games.append(text)
let indexPath = IndexPath(row: games.count - 1, section: 0)
tableView.beginUpdates()
tableView.insertRows(at: [indexPath], with: .fade)
tableView.endUpdates()
}
Or you can create a dedicated modal and present it from there. Communication back can be protocol delegate.
@objc
func addGameTapped() {
present(saveGameViewController, animated: true, completion: nil)
}