Skip to content
Snippets Groups Projects
Presenting.swift 3.43 KiB
Newer Older
Bruno Muniz's avatar
Bruno Muniz committed
import UIKit
import Theme

public protocol Presenting {
    func present(_ target: UIViewController..., from parent: UIViewController)
Bruno Muniz's avatar
Bruno Muniz committed
    func dismiss(from parent: UIViewController)
}

public extension Presenting {
    func dismiss(from parent: UIViewController) {
        parent.dismiss(animated: true)
    }
}

public struct PushPresenter: Presenting {
    public init() {}

    public func present(_ target: UIViewController..., from parent: UIViewController) {
        parent.navigationController?.pushViewController(target.first!, animated: true)
Bruno Muniz's avatar
Bruno Muniz committed
    }
}

public struct ModalPresenter: Presenting {
    public init() {}

    public func present(_ target: UIViewController..., from parent: UIViewController) {
        let statusBarVC = StatusBarViewController(target.first!)
Bruno Muniz's avatar
Bruno Muniz committed
        statusBarVC.modalPresentationStyle = .fullScreen
        parent.present(statusBarVC, animated: true)
    }
}

public struct ReplacePresenter: Presenting {
    public enum Mode {
        case replaceAll
        case replaceLast
        case replaceBackwards(AnyObject.Type)
    }

    var mode: Mode

    public init(mode: Mode = .replaceAll) {
        self.mode = mode
    }

    public func present(_ target: UIViewController..., from parent: UIViewController) {
Bruno Muniz's avatar
Bruno Muniz committed
        guard let navigationController = parent.navigationController else { return }

        switch mode {
        case .replaceAll:
            navigationController.setViewControllers(target, animated: true)
Bruno Muniz's avatar
Bruno Muniz committed

        case .replaceBackwards(let OlderInStack):
            if let oldScreen = navigationController.viewControllers.filter({ $0.isKind(of: OlderInStack.self) }).first,
               let index = navigationController.viewControllers.firstIndex(of: oldScreen) {

                let viewControllersBefore =
                    navigationController.viewControllers.dropLast(
                        navigationController.viewControllers.count - index
                    )

                if let coordinator = navigationController.transitionCoordinator {
                    coordinator.animate(alongsideTransition: nil) { _ in
                        navigationController.setViewControllers(viewControllersBefore + target , animated: true)
Bruno Muniz's avatar
Bruno Muniz committed
                    }
                } else {
                    navigationController.setViewControllers(viewControllersBefore + target , animated: true)
Bruno Muniz's avatar
Bruno Muniz committed
                }

            } else {
                navigationController.pushViewController(target.first!, animated: true)
Bruno Muniz's avatar
Bruno Muniz committed
            }
        case .replaceLast:
            let viewControllersBefore = navigationController.viewControllers.dropLast()

            func replace() {
                navigationController.setViewControllers(viewControllersBefore + target , animated: true)
Bruno Muniz's avatar
Bruno Muniz committed
            }

            if let coordinator = navigationController.transitionCoordinator {
                coordinator.animate(alongsideTransition: nil) { _ in
                    replace()
                }
            } else {
                replace()
            }
        }
    }
}

public struct PopReplacePresenter: Presenting {
    public init() {}

    public func present(_ target: UIViewController..., from parent: UIViewController) {
Bruno Muniz's avatar
Bruno Muniz committed
        if let lastViewController = parent.navigationController?.viewControllers.last {
            parent.navigationController?.setViewControllers([target.first!, lastViewController], animated: false)
            parent.navigationController?.setViewControllers([target.first!], animated: true)
Bruno Muniz's avatar
Bruno Muniz committed
        }
    }
}