Skip to content

Instantly share code, notes, and snippets.

@maxhand
Created September 28, 2024 18:09
Show Gist options
  • Save maxhand/f49fac47443d0f312b50f1f87c66651a to your computer and use it in GitHub Desktop.
Save maxhand/f49fac47443d0f312b50f1f87c66651a to your computer and use it in GitHub Desktop.
App Tint Settings
import UIKit
enum AccentViewSection: Hashable, CaseIterable { case main }
enum AppAccent: Int, Hashable, CaseIterable {
case blue = 0
case orange = 1
case red = 2
case purple = 3
var name: String {
switch self {
case .blue:
return "Blue"
case .orange:
return "Orange"
case .red:
return "Red"
case .purple:
return "Purple"
}
}
var color: UIColor {
switch self {
case .blue:
return .systemBlue
case .red:
return .systemRed
case .orange:
return .systemOrange
case .purple:
return .systemPurple
}
}
}
private class AccentViewDataSource: UICollectionViewDiffableDataSource<AccentViewSection, AppAccent> { }
private typealias AccentViewSnapshot = NSDiffableDataSourceSnapshot<AccentViewSection, AppAccent>
class AccentPickerViewController: UIViewController {
private var dataSource: AccentViewDataSource?
private var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
setupView()
makeDataSource()
applySnapshot()
}
private func setupView() {
title = "Accent"
collectionView = .init(frame: .zero, collectionViewLayout: makeLayout())
collectionView.delegate = self
view = collectionView
}
private func makeLayout() -> UICollectionViewCompositionalLayout {
.list(using: .init(appearance: .insetGrouped))
}
private func makeDataSource() {
dataSource = .init(collectionView: collectionView, cellProvider: { [unowned self] collectionView, indexPath, itemIdentifier in
collectionView.dequeueConfiguredReusableCell(using: accentCellRegistration, for: indexPath, item: itemIdentifier)
})
}
private func applySnapshot(animatingDifferences: Bool = false) {
var snapshot = AccentViewSnapshot()
snapshot.appendSections(AccentViewSection.allCases)
snapshot.appendItems(AppAccent.allCases, toSection: .main)
dataSource?.apply(snapshot, animatingDifferences: animatingDifferences)
}
private let accentCellRegistration: UICollectionView.CellRegistration<UICollectionViewListCell, AppAccent> = {
.init { cell, indexPath, itemIdentifier in
var contentConfiguration = cell.defaultContentConfiguration()
contentConfiguration.text = itemIdentifier.name
contentConfiguration.image = UIImage(
systemName: "circle.fill")?
.withConfiguration(
UIImage.SymbolConfiguration(
paletteColors: [itemIdentifier.color]
)
.applying(UIImage.SymbolConfiguration(scale: .medium))
)
cell.contentConfiguration = contentConfiguration
}
}()
}
extension AccentPickerViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.deselectItem(at: indexPath, animated: true)
guard let itemIdentifier = dataSource?.itemIdentifier(for: indexPath) else { return }
setAccent(itemIdentifier)
}
}
extension AccentPickerViewController {
private func setAccent(_ accent: AppAccent) {
UIApplication.keyWindow?.tintColor = accent.color
UserDefaults.appGroup.appTintColorRawValue = accent.rawValue
}
}
extension UIApplication {
static var keyWindow: UIWindow? {
let allScenes = UIApplication.shared.connectedScenes
for scene in allScenes {
guard let windowScene = scene as? UIWindowScene else { continue }
for window in windowScene.windows where window.isKeyWindow {
return window
}
}
return nil
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment