// // AppSplitViewController.swift // Reader // // Created by Shadowfacts on 1/14/22. // import UIKit #if targetEnvironment(macCatalyst) import AppKit #endif import Persistence class AppSplitViewController: UISplitViewController { private let fervorController: FervorController private var secondaryNav: UINavigationController! override var childForStatusBarHidden: UIViewController? { if traitCollection.horizontalSizeClass == .compact { return viewController(for: .compact) } else { return nil } } init(fervorController: FervorController) { self.fervorController = fervorController super.init(style: .doubleColumn) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() preferredDisplayMode = .oneBesideSecondary preferredSplitBehavior = .tile presentsWithGesture = true showsSecondaryOnlyButton = true primaryBackgroundStyle = .sidebar maximumPrimaryColumnWidth = 500 let sidebarHome = HomeViewController(fervorController: fervorController) sidebarHome.enableStretchyMenu = false sidebarHome.itemsDelegate = self let sidebarNav = UINavigationController(rootViewController: sidebarHome) sidebarNav.navigationBar.prefersLargeTitles = true setViewController(sidebarNav, for: .primary) secondaryNav = UINavigationController() #if targetEnvironment(macCatalyst) secondaryNav.isNavigationBarHidden = true #else // the toggle sidebar button only appears if there's a navigation bar // so we just make always transparent, rather than disabling it let secondaryNavBarAppearance = UINavigationBarAppearance() secondaryNavBarAppearance.configureWithTransparentBackground() secondaryNav.navigationBar.standardAppearance = secondaryNavBarAppearance #endif secondaryNav.view.backgroundColor = .appBackground setViewController(secondaryNav, for: .secondary) let home = HomeViewController(fervorController: fervorController) home.delegate = self let nav = AppNavigationController(rootViewController: home) setViewController(nav, for: .compact) } func stateRestorationActivity() -> NSUserActivity? { if traitCollection.horizontalSizeClass == .compact { let nav = viewController(for: .compact) as! UINavigationController let top = nav.topViewController! if top is ReadViewController || top is ItemsViewController { return top.userActivity } } else { if let read = secondaryNav.topViewController { return read.userActivity } else { let homeNav = viewController(for: .primary) as! UINavigationController if homeNav.topViewController is ItemsViewController { return homeNav.topViewController!.userActivity } } } return nil } func showItemList(_ type: ItemListType) { let column: Column if traitCollection.horizontalSizeClass == .compact { column = .compact } else { column = .primary } let nav = viewController(for: column) as! UINavigationController let home = nav.viewControllers.first! as! HomeViewController home.selectItem(type) } @discardableResult func showItem(_ item: Item) -> ReadViewController { if traitCollection.horizontalSizeClass == .compact { let nav = viewController(for: .compact) as! UINavigationController // todo: should we try to show the right items list? while nav.viewControllers.count > 2 { if let current = nav.topViewController as? ReadViewController, current.item == item { return current } else { nav.popViewController(animated: false) } } let read = ReadViewController(item: item, fervorController: fervorController) nav.pushViewController(read, animated: false) return read } else { if let current = secondaryNav.topViewController as? ReadViewController, current.item == item { return current } else { let read = ReadViewController(item: item, fervorController: fervorController) secondaryNav.setViewControllers([read], animated: false) return read } } } } extension AppSplitViewController: ItemsViewControllerDelegate { func showReadItem(_ item: Item) { secondaryNav.setViewControllers([ReadViewController(item: item, fervorController: fervorController)], animated: false) } } extension AppSplitViewController: HomeViewControllerDelegate { func switchToAccount(_ account: LocalData.Account) { if let delegate = view.window?.windowScene?.delegate as? SceneDelegate { Task { @MainActor in await delegate.switchToAccount(account) } } } }