Tab picker: Allow multiple selection/deletion
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user