单个 VIPER 模块中的多个视图控制器
Multiple View Controllers in a single VIPER module
我正在使用 VIPER 架构构建我的第一个应用程序。我有两个 VCs:主要的和模态的(从主要 VC 模态呈现)。我的模式 VC 中有一个 tableView,当用户在那里选择一行时,我需要将它传递给演示者,然后从演示者传递给主 VC。我还需要在模态 VC 中保持所选行突出显示,因此如果我关闭它然后再次显示它,该行仍将突出显示。我很困惑,因为我不知道最好的方法是什么。我尝试过的是将模态 VC 包含到配置器中并调用配置器两次:在主 VC 中,然后在模态 VC 中再次调用。它工作正常。这就是我的配置器的样子:
protocol ObserverConfiguratorProtocol {
func configure(with mainViewController: ObserverViewController, with modalViewController: CurrenciesViewController)
}
class ObserverConfigurator: ObserverConfiguratorProtocol {
func configure(with mainViewController: ObserverViewController, with modalViewController: CurrenciesViewController) {
let presenter = ObserverPresenter(view: mainViewController)
let interactor = ObserverInteractor(presenter: presenter)
let router = ObserverRouter(view: mainViewController)
mainViewController.presenter = presenter
modalViewController.presenter = presenter
presenter.interactor = interactor
presenter.router = router
presenter.view = mainViewController
presenter.modalView = modalViewController
}
}
主要 VC:
中的 viewDidLoad()
override func viewDidLoad() {
configurator.configure(with: self, view: CurrenciesViewController())
}
模态 VC:
中的 viewDidLoad()
override func viewDidLoad() {
configurator.configure(with: ObserverViewController(), view: self)
}
无论如何,我不确定它是否符合 VIPER 原则。是吗,或者有更好的解决方案?感谢您的帮助!
如果您要展示另一个视图控制器,它应该位于 VIPER 自己的模块中。 ObserverViewController
不应该知道 CurrenciesViewController
的存在。
相反,只有 ObserverRouter
应该知道如何构建 CurrenciesModule
并向其中呈现和传递数据。像这样:
final class CurrenciesBuilder {
@available(*, unavailable) private init() { }
static func build(routerDelegate: ObserverRouterDelegate, selectedIndex: IndexPath?) -> CurrenciesViewProtocol {
let service = CurrenciesService()
let interactor = CurrenciesInteractor(service: service, selectedIndex: selectedIndex)
let view = CurrenciesViewController(nibName: String(describing: CurrenciesViewController.self), bundle: nil)
let router = CurrenciesRouter(vc: view)
router.delegate = routerDelegate
let presenter = CurrenciesPresenter(interactor: interactor,
view: view,
router: router)
view.presenter = presenter
return view
}
}
因此,每当您需要显示 CurrenciesViewController
时,您可以传递 selectedIndex
并且它可以突出显示它(如果适用)。我会将信息传递给交互器,让演示者知道并在视图中做一些更改。
为了将 selectedIndex
传回 ObserverViewController
,您可以创建一个 ObserverRouterDelegate
,它可以在 CurrenciesViewController
将被关闭时触发。
protocol ObserverRouterDelegate: AnyObject {
func didDismiss(with selectedIndex: IndexPath?)
}
总结;应该有 2 个模块,ObserverModule
和 CurrenciesModule
,它们应该通过它们的路由器进行双向连接。由于路由器负责 presenting/dismissing 视图(并且它们与它们的视图保持连接),它们可以更新它们的视图 and/or 让对等路由器更新它们自己的视图。
我正在使用 VIPER 架构构建我的第一个应用程序。我有两个 VCs:主要的和模态的(从主要 VC 模态呈现)。我的模式 VC 中有一个 tableView,当用户在那里选择一行时,我需要将它传递给演示者,然后从演示者传递给主 VC。我还需要在模态 VC 中保持所选行突出显示,因此如果我关闭它然后再次显示它,该行仍将突出显示。我很困惑,因为我不知道最好的方法是什么。我尝试过的是将模态 VC 包含到配置器中并调用配置器两次:在主 VC 中,然后在模态 VC 中再次调用。它工作正常。这就是我的配置器的样子:
protocol ObserverConfiguratorProtocol {
func configure(with mainViewController: ObserverViewController, with modalViewController: CurrenciesViewController)
}
class ObserverConfigurator: ObserverConfiguratorProtocol {
func configure(with mainViewController: ObserverViewController, with modalViewController: CurrenciesViewController) {
let presenter = ObserverPresenter(view: mainViewController)
let interactor = ObserverInteractor(presenter: presenter)
let router = ObserverRouter(view: mainViewController)
mainViewController.presenter = presenter
modalViewController.presenter = presenter
presenter.interactor = interactor
presenter.router = router
presenter.view = mainViewController
presenter.modalView = modalViewController
}
}
主要 VC:
中的 viewDidLoad() override func viewDidLoad() {
configurator.configure(with: self, view: CurrenciesViewController())
}
模态 VC:
中的 viewDidLoad() override func viewDidLoad() {
configurator.configure(with: ObserverViewController(), view: self)
}
无论如何,我不确定它是否符合 VIPER 原则。是吗,或者有更好的解决方案?感谢您的帮助!
如果您要展示另一个视图控制器,它应该位于 VIPER 自己的模块中。 ObserverViewController
不应该知道 CurrenciesViewController
的存在。
相反,只有 ObserverRouter
应该知道如何构建 CurrenciesModule
并向其中呈现和传递数据。像这样:
final class CurrenciesBuilder {
@available(*, unavailable) private init() { }
static func build(routerDelegate: ObserverRouterDelegate, selectedIndex: IndexPath?) -> CurrenciesViewProtocol {
let service = CurrenciesService()
let interactor = CurrenciesInteractor(service: service, selectedIndex: selectedIndex)
let view = CurrenciesViewController(nibName: String(describing: CurrenciesViewController.self), bundle: nil)
let router = CurrenciesRouter(vc: view)
router.delegate = routerDelegate
let presenter = CurrenciesPresenter(interactor: interactor,
view: view,
router: router)
view.presenter = presenter
return view
}
}
因此,每当您需要显示 CurrenciesViewController
时,您可以传递 selectedIndex
并且它可以突出显示它(如果适用)。我会将信息传递给交互器,让演示者知道并在视图中做一些更改。
为了将 selectedIndex
传回 ObserverViewController
,您可以创建一个 ObserverRouterDelegate
,它可以在 CurrenciesViewController
将被关闭时触发。
protocol ObserverRouterDelegate: AnyObject {
func didDismiss(with selectedIndex: IndexPath?)
}
总结;应该有 2 个模块,ObserverModule
和 CurrenciesModule
,它们应该通过它们的路由器进行双向连接。由于路由器负责 presenting/dismissing 视图(并且它们与它们的视图保持连接),它们可以更新它们的视图 and/or 让对等路由器更新它们自己的视图。