1

I've been looking for an elegant solution for some time without happiness.

I want to:

  • solve the massive viewcontroller problem that VIPER, MVVM, et al address,
  • always animate transition between fully rendered screens.

This feels like fighting the Apple frameworks; view controllers are in the drivers' seat of the navigation flow. I'm thinking to reverse that and do overall navigation in code, but the question is what kind of objects to create that own the view controllers, and when to instantiate. Activity indicators will be on the source scenes.

Yann Bodson
  • 1,634
  • 1
  • 17
  • 29
Jim Stead
  • 21
  • 2

1 Answers1

0

Don't give up fighting against Apple MVC framework!

Having the module initialization code on its own Router will eliminate a bunch of code repetition, specially for huge projects. You need to create these extensions once:

// ReusableView.swift
protocol ReusableView: class {}

extension ReusableView {
    static var reuseIdentifier: String {
        return String(describing: self)
    }
}


// UIViewController.swift
extension UIViewController: ReusableView { }


// UIStoryboard.swift
extension UIStoryboard {
    func instantiateViewController() -> T where T: ReusableView {
        return instantiateViewController(withIdentifier: T.reuseIdentifier) as! T
    }
}

And then, leave initialization code on the router of each VIPER module:

// MainSearchRouter.swift
class MainSearchRouter {

    // MARK: Properties
    weak var view: UIViewController?

    // MARK: Static methods
    static func setupModule() -> MainSearchViewController {
        let viewController = UIStoryboard(name: MainSearchViewController.storyboardName, bundle: nil).instantiateViewController() as MainSearchViewController
        let presenter = MainSearchPresenter()
        let router = MainSearchRouter()
        let interactor = MainSearchInteractor()

        viewController.presenter =  presenter

        presenter.view = viewController
        presenter.router = router
        presenter.interactor = interactor

        router.view = viewController

        interactor.output = presenter

        return viewController
    }
}

It might seem like a lot of steps, but good news: the aforementioned plugin automates that as well!

Marcelo Gracietti
  • 3,121
  • 1
  • 16
  • 24