Files
GitHawk/Classes/View Controllers/SplitViewControllerDelegate.swift
2017-09-26 18:08:45 -04:00

96 lines
3.5 KiB
Swift

//
// SplitViewControllerDelegate.swift
// Freetime
//
// Created by Ryan Nystrom on 6/25/17.
// Copyright © 2017 Ryan Nystrom. All rights reserved.
//
import UIKit
// add this shell protocol onto a view controller that should remain part of a tab's root nav VC when splitting out
// detail VCs from primary on split VC expansion
protocol PrimaryViewController {}
final class SplitViewControllerDelegate: UISplitViewControllerDelegate {
func splitViewController(
_ splitViewController: UISplitViewController,
collapseSecondary secondaryViewController: UIViewController,
onto primaryViewController: UIViewController
) -> Bool {
if let tab = primaryViewController as? UITabBarController,
let primaryNav = tab.selectedViewController as? UINavigationController,
let secondaryNav = secondaryViewController as? UINavigationController {
// remove any placeholder VCs from the stack
primaryNav.viewControllers += secondaryNav.viewControllers.filter {
$0.hidesBottomBarWhenPushed = true
return ($0 is SplitPlaceholderViewController) == false
}
}
return true
}
func splitViewController(
_ splitViewController: UISplitViewController,
separateSecondaryFrom primaryViewController: UIViewController
) -> UIViewController? {
guard let tab = primaryViewController as? UITabBarController,
let primaryNav = tab.selectedViewController as? UINavigationController
else { return nil }
var detailVCs = [UIViewController]()
// for each tab VC that is a nav controller, pluck everything that isn't marked as a primary VC off of
// the nav stack. if the nav is the currently selected tab VC, then move all non-primary VCs to
for tabVC in tab.viewControllers ?? [] {
// they should all be navs, but just in case
guard let nav = tabVC as? UINavigationController else { continue }
// pop until hitting a VC marked as "primary"
while let top = nav.topViewController,
top !== nav.viewControllers.first,
(top is PrimaryViewController) == false {
if nav === primaryNav {
detailVCs.insert(top, at: 0)
}
nav.popViewController(animated: false)
}
}
if detailVCs.count > 0 {
// if there are active VCs, push them onto the new nav stack
let nav = UINavigationController()
nav.setViewControllers(detailVCs, animated: false)
return nav
} else {
// otherwise use a placeholder VC
return UINavigationController(rootViewController: SplitPlaceholderViewController())
}
}
func splitViewController(
_ splitViewController: UISplitViewController,
showDetail vc: UIViewController,
sender: Any?
) -> Bool {
guard let tab = splitViewController.viewControllers.first as? UITabBarController
else { return false }
if splitViewController.isCollapsed {
if let nav = vc as? UINavigationController, let first = nav.viewControllers.first {
tab.selectedViewController?.show(first, sender: sender)
} else {
tab.selectedViewController?.show(vc, sender: sender)
}
} else {
splitViewController.viewControllers = [tab, vc]
}
return true
}
}