// // AccountSwitchingContainerViewController.swift // Tusker // // Created by Shadowfacts on 11/11/20. // Copyright © 2020 Shadowfacts. All rights reserved. // import UIKit import ScreenCorners class AccountSwitchingContainerViewController: UIViewController { private(set) var root: TuskerRootViewController init(root: TuskerRootViewController) { self.root = root super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() embedChild(root) } func setRoot(_ newRoot: TuskerRootViewController, animating direction: AnimationDirection) { let oldRoot = self.root if direction == .none { oldRoot.removeViewAndController() } self.root = newRoot embedChild(newRoot) if direction != .none { if UIAccessibility.prefersCrossFadeTransitions { newRoot.view.alpha = 0 UIView.animate(withDuration: 0.4, delay: 0, options: .curveEaseInOut) { newRoot.view.alpha = 1 oldRoot.view.alpha = 0 } completion: { (_) in oldRoot.removeViewAndController() } } else { let sign: CGFloat = direction == .downwards ? -1 : 1 let newInitialOffset = sign * view.bounds.height let scale: CGFloat = 0.75 newRoot.view.transform = CGAffineTransform(translationX: 0, y: newInitialOffset).scaledBy(x: 0.9, y: 0.9) newRoot.view.layer.masksToBounds = true newRoot.view.layer.cornerCurve = .continuous newRoot.view.layer.cornerRadius = view.window?.screen.displayCornerRadius ?? 0 oldRoot.view.layer.masksToBounds = true oldRoot.view.layer.cornerCurve = .continuous oldRoot.view.layer.cornerRadius = view.window?.screen.displayCornerRadius ?? 0 // only one edge is affected in each direction, i have no idea why if direction == .upwards { oldRoot.additionalSafeAreaInsets.bottom = view.safeAreaInsets.bottom } else { oldRoot.additionalSafeAreaInsets.top = view.safeAreaInsets.top } UIView.animate(withDuration: 0.4, delay: 0, options: .curveEaseInOut) { oldRoot.view.transform = CGAffineTransform(translationX: 0, y: -newInitialOffset).scaledBy(x: scale, y: scale) newRoot.view.transform = .identity } completion: { (_) in oldRoot.removeViewAndController() newRoot.view.layer.masksToBounds = false } } } } } extension AccountSwitchingContainerViewController { enum AnimationDirection { case none, downwards, upwards } } extension AccountSwitchingContainerViewController: TuskerRootViewController { func presentCompose() { loadViewIfNeeded() root.presentCompose() } func select(tab: MainTabBarViewController.Tab) { loadViewIfNeeded() root.select(tab: tab) } func getTabController(tab: MainTabBarViewController.Tab) -> UIViewController? { loadViewIfNeeded() return root.getTabController(tab: tab) } func performSearch(query: String) { loadViewIfNeeded() root.performSearch(query: query) } func presentPreferences(completion: (() -> Void)?) { loadViewIfNeeded() root.presentPreferences(completion: completion) } func handleStatusBarTapped(xPosition: CGFloat) -> StatusBarTapActionResult { loadViewIfNeeded() // TODO: check if fast account switcher is being presented? return root.handleStatusBarTapped(xPosition: xPosition) } } extension AccountSwitchingContainerViewController: BackgroundableViewController { func sceneDidEnterBackground() { if let backgroundable = root as? BackgroundableViewController { backgroundable.sceneDidEnterBackground() } } }