Created
August 2, 2017 12:28
-
-
Save Oni-zerone/a000a74b3d02ef47bd22a9c4ae74a2ef to your computer and use it in GitHub Desktop.
SOTTabViewContainer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// TabViewContainer.swift | |
// BusMap | |
// | |
// Created by Andrea Altea on 24/05/17. | |
// Copyright © 2017 StudiOUT. All rights reserved. | |
// | |
import UIKit | |
class TabViewContainer: UIViewController { | |
//MARK: - Config | |
struct Notification { | |
static let ShowMenu = NSNotification.Name("TabViewContainerShowMenuNotification") | |
static let ShowContent = NSNotification.Name("TabViewContainerShowContentNotification") | |
} | |
//MARK: - Model | |
var builder:TabControllerBuilder? { | |
didSet { | |
self.detailControllers = Dictionary<NSInteger, UIViewController>() | |
self.showController(at: 0) | |
} | |
} | |
var detailControllers: Dictionary<NSInteger, UIViewController> = Dictionary<NSInteger, UIViewController>() | |
fileprivate(set) weak var currentController:UIViewController? | |
fileprivate weak var menuController: UIViewController? | |
//MARK: - Lifecycle | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
NotificationCenter.default.addObserver(forName: Notification.ShowMenu, object: nil, queue: nil) { (notification) in | |
self.showMenu() | |
} | |
} | |
override func didReceiveMemoryWarning() { | |
super.didReceiveMemoryWarning() | |
let discardableItems = self.detailControllers.filter { (key: NSInteger, value: UIViewController) -> Bool in | |
return value != self.currentController | |
} | |
discardableItems.forEach { (key: NSInteger, value: UIViewController) in | |
self.detailControllers.removeValue(forKey: key) | |
} | |
} | |
deinit { | |
NotificationCenter.default.removeObserver(self) | |
} | |
} | |
fileprivate typealias TabViewContainerContent = TabViewContainer | |
extension TabViewContainerContent { | |
func showController(at index: NSInteger) { | |
if self.detailControllers[index] == nil { | |
self.detailControllers[index] = self.builder?.controller(at: index) | |
} | |
guard let detailController = detailControllers[index] else { | |
return | |
} | |
self.insertDetailController(detailController) | |
self.hideMenu() | |
} | |
private func insertDetailController(_ controller: UIViewController) { | |
self.removeDetailController() | |
self.insertChildController(controller) | |
self.currentController = controller | |
} | |
private func removeDetailController() { | |
guard let currentController = self.currentController else { | |
return | |
} | |
currentController.willMove(toParentViewController: nil) | |
currentController.removeFromParentViewController() | |
currentController.view.removeFromSuperview() | |
} | |
} | |
fileprivate typealias TabViewContainerMenu = TabViewContainer | |
extension TabViewContainerMenu: TabMenuControllerDelegate { | |
func showMenu() { | |
if(self.menuController != nil) { | |
return | |
} | |
guard let builder = self.builder else { | |
return | |
} | |
let menuController = builder.menuController() | |
menuController.dataSource = builder as? TabMenuControllerDataSource ?? nil | |
menuController.delegate = self | |
self.insertChildController(menuController) | |
self.menuController = menuController | |
} | |
func hideMenu() { | |
guard let menuController = self.menuController else { | |
return | |
} | |
menuController.willMove(toParentViewController: nil) | |
menuController.removeFromParentViewController() | |
menuController.view.removeFromSuperview() | |
} | |
//MARK: TabMenuControllerDelegate | |
func controller(_ controller: TabMenuController, didSelectItemAtIndex index: NSInteger) { | |
self.showController(at: index) | |
} | |
func dismissMenuFromController(_ controller: TabMenuController) { | |
self.hideMenu() | |
} | |
} | |
fileprivate extension UIViewController { | |
func insertChildController(_ controller: UIViewController) { | |
self.addChildViewController(controller) | |
controller.view.frame = self.view.frame | |
controller.view.translatesAutoresizingMaskIntoConstraints = false | |
self.view.addSubview(controller.view) | |
let viewDictionary: Dictionary<String, UIView> = ["view": controller.view] | |
let hConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[view]-0-|", | |
options: NSLayoutFormatOptions(rawValue: 0), | |
metrics: nil, | |
views: viewDictionary) | |
let vConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[view]-0-|", | |
options: NSLayoutFormatOptions(rawValue: 0), | |
metrics: nil, | |
views: viewDictionary) | |
self.view.addConstraints(hConstraints) | |
self.view.addConstraints(vConstraints) | |
controller.didMove(toParentViewController: self) | |
setNeedsStatusBarAppearanceUpdate() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment