Skip to content

Instantly share code, notes, and snippets.

@conscientiousness
Created April 26, 2018 02:19
Show Gist options
  • Save conscientiousness/b918001f6575558bd1bd6294a0217ffa to your computer and use it in GitHub Desktop.
Save conscientiousness/b918001f6575558bd1bd6294a0217ffa to your computer and use it in GitHub Desktop.
//
// Navigator.swift
// tripani
//
// Created by Jesse Lin on 11/8/17.
// Copyright © 2017 Tripani. All rights reserved.
//
import Foundation
import UIKit
import SafariServices
import ESTabBarController_swift
protocol Navigatable {
var navigator: Navigator! { get set }
}
class Navigator {
static var `default`: Navigator = { return Navigator() }()
private lazy var tabBarController = TPTabBarController()
// MARK: - segues list
enum Scene {
enum Transition {
case root(in: UIWindow)
case navigation, modal
}
// all app scenes
case tabs
//case profileTab(ProfilePagerType)
case webPage(URL)
}
// MARK: - get a single VC
func get(segue: Scene, storyboard: UIStoryboard) -> UIViewController {
switch segue {
case .tabs:
return tabBarController
// case .profileTab(let type):
// let vm = ProfileInfoTabViewModel()
// return ProfileInfoTabVC.createWith(R.storyboard.profile(), viewModel: vm, type: type)
case .webPage(let url):
let safari = SFSafariViewController(url: url)
safari.hidesBottomBarWhenPushed = true
return safari
}
}
func show(segue: Scene, sender: UIViewController?, transition: Scene.Transition = .navigation) {
let storyboard = sender?.storyboard ?? R.storyboard.main()
let target = get(segue: segue, storyboard: storyboard)
show(target: target, sender: sender, transition: transition)
}
// MARK: - Private Method
private func show(target: UIViewController, sender: UIViewController?, transition: Scene.Transition) {
injectNavigator(in: target)
switch transition {
case .root(in: let window):
UIView.transition(with: window, duration: 0.5, options: .transitionFlipFromLeft, animations: {
window.rootViewController = target
}, completion: nil)
return;
default: break
}
guard let sender = sender else {
fatalError("You need to pass in a sender for .navigation or .modal transitions")
}
if let nav = sender as? UINavigationController {
//push root controller on navigation stack
nav.pushViewController(target, animated: false)
return
}
switch transition {
case .navigation:
if let nav = sender.navigationController {
//add controller to navigation stack
nav.pushViewController(target, animated: true)
}
case .modal:
//present modally
sender.present(target, animated: true, completion: nil)
default: break
}
}
private func injectNavigator(in target: UIViewController) {
// view controller
if var target = target as? Navigatable {
target.navigator = self
return
}
// tabs
if let target = target as? UITabBarController, let children = target.viewControllers {
for vc in children {
injectNavigator(in: vc)
}
}
// navigation controller
if let target = target as? UINavigationController, let root = target.viewControllers.first {
injectNavigator(in: root)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment