123 lines
4.8 KiB
Swift
123 lines
4.8 KiB
Swift
//
|
|
// SwipeActionsPrefsView.swift
|
|
// Tusker
|
|
//
|
|
// Created by Shadowfacts on 11/26/22.
|
|
// Copyright © 2022 Shadowfacts. All rights reserved.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct SwipeActionsPrefsView: UIViewControllerRepresentable {
|
|
@Binding var selection: [StatusSwipeAction]
|
|
|
|
typealias UIViewControllerType = SwipeActionsPrefsViewController
|
|
|
|
func makeUIViewController(context: Context) -> SwipeActionsPrefsViewController {
|
|
return SwipeActionsPrefsViewController(selection: $selection)
|
|
}
|
|
|
|
func updateUIViewController(_ uiViewController: SwipeActionsPrefsViewController, context: Context) {
|
|
}
|
|
}
|
|
|
|
class SwipeActionsPrefsViewController: UIViewController, UICollectionViewDelegate {
|
|
@Binding var selection: [StatusSwipeAction]
|
|
|
|
private var collectionView: UICollectionView {
|
|
view as! UICollectionView
|
|
}
|
|
private var dataSource: UICollectionViewDiffableDataSource<Section, Item>!
|
|
|
|
init(selection: Binding<[StatusSwipeAction]>) {
|
|
self._selection = selection
|
|
|
|
super.init(nibName: nil, bundle: nil)
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override func loadView() {
|
|
let layout = UICollectionViewCompositionalLayout { [unowned self] sectionIndex, environment in
|
|
var config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
|
|
if dataSource.sectionIdentifier(for: sectionIndex) == .selected {
|
|
config.headerMode = .supplementary
|
|
}
|
|
return .list(using: config, layoutEnvironment: environment)
|
|
}
|
|
view = UICollectionView(frame: .zero, collectionViewLayout: layout)
|
|
collectionView.delegate = self
|
|
dataSource = createDataSource()
|
|
}
|
|
|
|
private func createDataSource() -> UICollectionViewDiffableDataSource<Section, Item> {
|
|
let listCell = UICollectionView.CellRegistration<UICollectionViewListCell, StatusSwipeAction> { cell, indexPath, item in
|
|
var config = cell.defaultContentConfiguration()
|
|
config.text = item.displayName
|
|
config.image = UIImage(systemName: item.systemImageName)
|
|
cell.contentConfiguration = config
|
|
cell.accessories = [.reorder(displayed: .always)]
|
|
}
|
|
let dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in
|
|
return collectionView.dequeueConfiguredReusableCell(using: listCell, for: indexPath, item: itemIdentifier)
|
|
}
|
|
let headerCell = UICollectionView.SupplementaryRegistration<UICollectionViewListCell>(elementKind: UICollectionView.elementKindSectionHeader) { supplementaryView, elementKind, indexPath in
|
|
var config = supplementaryView.defaultContentConfiguration()
|
|
config.text = "Selected"
|
|
supplementaryView.contentConfiguration = config
|
|
}
|
|
dataSource.supplementaryViewProvider = { collectionView, kind, indexPath in
|
|
return collectionView.dequeueConfiguredReusableSupplementary(using: headerCell, for: indexPath)
|
|
}
|
|
dataSource.reorderingHandlers.canReorderItem = { _ in
|
|
return true
|
|
}
|
|
dataSource.reorderingHandlers.didReorder = { [unowned self] transaction in
|
|
guard let selectedSection = transaction.sectionTransactions.first(where: { $0.sectionIdentifier == .selected }) else {
|
|
return
|
|
}
|
|
self.selection = self.selection.applying(selectedSection.difference)!
|
|
}
|
|
return dataSource
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
setEditing(true, animated: false)
|
|
applySnapshot(animated: false)
|
|
}
|
|
|
|
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
|
collectionView.deselectItem(at: indexPath, animated: true)
|
|
guard let item = dataSource.itemIdentifier(for: indexPath),
|
|
let section = dataSource.sectionIdentifier(for: indexPath.section) else {
|
|
return
|
|
}
|
|
switch section {
|
|
case .selected:
|
|
selection.removeAll(where: { $0 == item })
|
|
case .remainder:
|
|
selection.append(item)
|
|
}
|
|
applySnapshot(animated: true)
|
|
}
|
|
|
|
private func applySnapshot(animated: Bool) {
|
|
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
|
snapshot.appendSections([.selected, .remainder])
|
|
snapshot.appendItems(selection, toSection: .selected)
|
|
snapshot.appendItems(StatusSwipeAction.allCases.filter { !selection.contains($0) }, toSection: .remainder)
|
|
dataSource.apply(snapshot, animatingDifferences: animated)
|
|
}
|
|
|
|
enum Section {
|
|
case selected
|
|
case remainder
|
|
}
|
|
|
|
typealias Item = StatusSwipeAction
|
|
}
|