189 lines
6.8 KiB
Swift
189 lines
6.8 KiB
Swift
import Eureka
|
|
import Foundation
|
|
import Shared
|
|
import UIKit
|
|
|
|
@objc class SettingsSceneDelegate: BasicSceneDelegate {
|
|
private var navigationController: UINavigationController? {
|
|
didSet {
|
|
if let navigationController {
|
|
navigationController.delegate = self
|
|
update(navigationController: navigationController)
|
|
}
|
|
}
|
|
}
|
|
|
|
override func basicConfig(in traitCollection: UITraitCollection) -> BasicSceneDelegate.BasicConfig {
|
|
.init(
|
|
title: L10n.Settings.NavigationBar.title,
|
|
rootViewController: {
|
|
if traitCollection.userInterfaceIdiom == .mac {
|
|
// root will be set when connecting scene
|
|
return UINavigationController()
|
|
} else {
|
|
return UINavigationController(rootViewController: SettingsViewController())
|
|
}
|
|
}()
|
|
)
|
|
}
|
|
|
|
override func scene(
|
|
_ scene: UIScene,
|
|
willConnectTo session: UISceneSession,
|
|
options connectionOptions: UIScene.ConnectionOptions
|
|
) {
|
|
super.scene(scene, willConnectTo: session, options: connectionOptions)
|
|
|
|
if let navigationController = window?.rootViewController as? UINavigationController {
|
|
self.navigationController = navigationController
|
|
}
|
|
|
|
guard let scene = scene as? UIWindowScene else { return }
|
|
|
|
#if targetEnvironment(macCatalyst)
|
|
if let titlebar = scene.titlebar {
|
|
if scene.traitCollection.userInterfaceIdiom == .mac {
|
|
titlebar.titleVisibility = .visible
|
|
titlebar.toolbarStyle = .preference
|
|
|
|
titlebar.toolbar = with(NSToolbar()) {
|
|
$0.delegate = self
|
|
|
|
if let identifier = SettingsRootDataSource.buttonRows.first?.toolbarItemIdentifier {
|
|
$0.selectedItemIdentifier = identifier
|
|
selectItemForIdentifier(identifier)
|
|
}
|
|
}
|
|
} else {
|
|
titlebar.titleVisibility = .hidden
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
func pushActions(animated: Bool) {
|
|
if window?.traitCollection.userInterfaceIdiom == .mac {
|
|
#if targetEnvironment(macCatalyst)
|
|
let identifier = SettingsRootDataSource.Row.actions.row.toolbarItemIdentifier
|
|
scene?.titlebar?.toolbar?.selectedItemIdentifier = identifier
|
|
selectItemForIdentifier(identifier)
|
|
#endif
|
|
} else {
|
|
navigationController?.pushViewController(
|
|
with(SettingsDetailViewController()) {
|
|
$0.detailGroup = .actions
|
|
},
|
|
animated: animated
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
extension SettingsSceneDelegate: UINavigationControllerDelegate {
|
|
private func update(navigationController: UINavigationController) {
|
|
if navigationController.traitCollection.userInterfaceIdiom == .mac {
|
|
let shouldBeHidden = navigationController.viewControllers.count <= 1
|
|
|
|
if #available(iOS 16, *) {
|
|
navigationController.navigationBar.preferredBehavioralStyle = .pad
|
|
}
|
|
|
|
if navigationController.isNavigationBarHidden != shouldBeHidden {
|
|
navigationController.setNavigationBarHidden(shouldBeHidden, animated: true)
|
|
}
|
|
}
|
|
}
|
|
|
|
func navigationController(
|
|
_ navigationController: UINavigationController,
|
|
willShow viewController: UIViewController,
|
|
animated: Bool
|
|
) {
|
|
update(navigationController: navigationController)
|
|
navigationController.transitionCoordinator?.animate(
|
|
alongsideTransition: nil,
|
|
completion: { [weak self] context in
|
|
if context.isCancelled {
|
|
self?.update(navigationController: navigationController)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
#if targetEnvironment(macCatalyst)
|
|
extension SettingsButtonRow {
|
|
var toolbarItemIdentifier: NSToolbarItem.Identifier {
|
|
.init(rawValue: tag ?? title ?? "")
|
|
}
|
|
}
|
|
|
|
extension SettingsSceneDelegate: NSToolbarDelegate {
|
|
func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
|
|
SettingsRootDataSource.buttonRows.filter(\.isAvailableForMac).map(\.toolbarItemIdentifier)
|
|
}
|
|
|
|
func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
|
|
toolbarDefaultItemIdentifiers(toolbar)
|
|
}
|
|
|
|
func toolbarSelectableItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
|
|
toolbarDefaultItemIdentifiers(toolbar)
|
|
}
|
|
|
|
func toolbar(
|
|
_ toolbar: NSToolbar,
|
|
itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier,
|
|
willBeInsertedIntoToolbar flag: Bool
|
|
) -> NSToolbarItem? {
|
|
guard let tab = SettingsRootDataSource.buttonRows.first(where: { $0.tag == itemIdentifier.rawValue }) else {
|
|
return nil
|
|
}
|
|
|
|
return with(NSToolbarItem(itemIdentifier: itemIdentifier)) {
|
|
$0.image = tab.icon?
|
|
.image(ofSize: CGSize(width: 32.0, height: 32.0), color: .black)
|
|
.withRenderingMode(.alwaysTemplate)
|
|
$0.label = tab.title ?? ""
|
|
$0.target = self
|
|
$0.action = #selector(selectItem)
|
|
}
|
|
}
|
|
|
|
@objc private func selectItem(_ item: NSToolbarItem) {
|
|
selectItemForIdentifier(item.itemIdentifier)
|
|
}
|
|
|
|
fileprivate func selectItemForIdentifier(_ identifier: NSToolbarItem.Identifier) {
|
|
if let viewController = viewController(for: identifier), let navigationController {
|
|
scene?.title = SettingsRootDataSource.buttonRows.first(where: { $0.tag == identifier.rawValue })?.title
|
|
|
|
// before, so it can be reset by the controller
|
|
navigationController.setToolbarHidden(true, animated: false)
|
|
|
|
navigationController.setViewControllers([viewController], animated: false)
|
|
|
|
// make sure we're not hiding content by accident
|
|
viewController.loadViewIfNeeded()
|
|
assert(
|
|
(viewController.navigationItem.rightBarButtonItems ?? []).isEmpty &&
|
|
(viewController.navigationItem.leftBarButtonItems ?? []).isEmpty,
|
|
"we hide the root view controller's navigation bar, so items aren't visible"
|
|
)
|
|
}
|
|
}
|
|
|
|
fileprivate func viewController(for itemIdentifier: NSToolbarItem.Identifier) -> UIViewController? {
|
|
guard let tab = SettingsRootDataSource.buttonRows.first(where: { $0.tag == itemIdentifier.rawValue }) else {
|
|
return nil
|
|
}
|
|
|
|
guard case let .show(controllerProvider: .callback(builder: block), _) = tab.presentationMode else {
|
|
return nil
|
|
}
|
|
|
|
return block()
|
|
}
|
|
}
|
|
#endif
|