Tab picker: Allow multiple selection/deletion

This commit is contained in:
James Magahern
2021-02-11 19:20:06 -08:00
parent 94b0f4348c
commit 09c6204a73
5 changed files with 112 additions and 22 deletions

View File

@@ -7,7 +7,7 @@
import UIKit
protocol TabPickerViewControllerDelegate: class
protocol TabPickerViewControllerDelegate: AnyObject
{
func tabPicker(_ picker: TabPickerViewController, didSelectTab tab: Tab)
func tabPicker(_ picker: TabPickerViewController, willCloseTab tab: Tab)
@@ -22,9 +22,27 @@ class TabPickerViewController: UIViewController, UICollectionViewDelegate
typealias TabID = UUID
private var selectedTabsForEditing: Set<Tab> = []
private var collectionView: UICollectionView?
private var dataSource: UICollectionViewDiffableDataSource<Int, TabID>?
override var traitCollection: UITraitCollection {
get { return super.traitCollection.alwaysPadLike() }
}
private lazy var newTabButton: UIBarButtonItem = {
UIBarButtonItem(systemItem: .add, primaryAction: UIAction(handler: { [unowned self] _ in
let newTab = self.tabController.createNewTab(url: nil)
self.delegate?.tabPicker(self, didSelectTab: newTab)
}), menu: nil)
}()
lazy var deleteTabButton: UIBarButtonItem = {
UIBarButtonItem(systemItem: .trash, primaryAction: UIAction(handler: { [unowned self] _ in
deleteSelectedTabs()
}), menu: nil)
}()
init(tabController: TabController) {
self.tabController = tabController
super.init(nibName: nil, bundle: nil)
@@ -58,6 +76,8 @@ class TabPickerViewController: UIViewController, UICollectionViewDelegate
let listLayout = UICollectionViewCompositionalLayout.list(using: listConfig)
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: listLayout)
collectionView.allowsMultipleSelectionDuringEditing = true
collectionView.backgroundColor = .systemGroupedBackground
let registry = UICollectionView.CellRegistration<UICollectionViewListCell, TabID> { [unowned self] (listCell, indexPath, item) in
var config = listCell.defaultContentConfiguration()
@@ -85,7 +105,7 @@ class TabPickerViewController: UIViewController, UICollectionViewDelegate
config.imageProperties.maximumSize = CGSize(width: 21.0, height: 21.0)
config.imageProperties.cornerRadius = 3.0
if tab == self.selectedTab {
if self.selectedTab == tab {
listCell.accessories = [ .checkmark() ]
} else {
listCell.accessories = []
@@ -114,16 +134,68 @@ class TabPickerViewController: UIViewController, UICollectionViewDelegate
self.collectionView = collectionView
self.view = self.collectionView
let newTabButton = UIBarButtonItem(systemItem: .add, primaryAction: UIAction(handler: { [unowned self] _ in
let newTab = self.tabController.createNewTab(url: nil)
self.delegate?.tabPicker(self, didSelectTab: newTab)
}), menu: nil)
configureNavigationButtons(forEditing: isEditing)
}
private func configureNavigationButtons(forEditing: Bool) {
if !forEditing {
navigationItem.rightBarButtonItem = newTabButton
} else {
deleteTabButton.isEnabled = collectionView?.indexPathsForSelectedItems?.count ?? 0 > 0
navigationItem.rightBarButtonItem = deleteTabButton
}
navigationItem.rightBarButtonItem = newTabButton
navigationItem.leftBarButtonItem = editButtonItem
}
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
if let collectionView = collectionView {
collectionView.isEditing = editing
}
configureNavigationButtons(forEditing: editing)
}
private func deleteSelectedTabs() {
guard let dataSource = dataSource else { return }
var snapshot = dataSource.snapshot()
for tab in selectedTabsForEditing {
snapshot.deleteItems([ tab.identifier ])
self.delegate?.tabPicker(self, willCloseTab: tab)
self.tabController.closeTab(tab)
}
dataSource.apply(snapshot, animatingDifferences: true)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let tab = tabController.tabs[indexPath.row]
delegate?.tabPicker(self, didSelectTab: tab)
if !isEditing {
delegate?.tabPicker(self, didSelectTab: tab)
} else {
deleteTabButton.isEnabled = collectionView.indexPathsForSelectedItems?.count ?? 0 > 0
selectedTabsForEditing.update(with: tab)
}
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
if isEditing {
let tab = tabController.tabs[indexPath.row]
selectedTabsForEditing.remove(tab)
deleteTabButton.isEnabled = collectionView.indexPathsForSelectedItems?.count ?? 0 > 0
}
}
func collectionView(_ collectionView: UICollectionView, shouldBeginMultipleSelectionInteractionAt indexPath: IndexPath) -> Bool {
true
}
func collectionView(_ collectionView: UICollectionView, didBeginMultipleSelectionInteractionAt indexPath: IndexPath) {
isEditing = true
}
}