MVVM-Cアーキテクチャで遊んでいますが、タブが選択されたときに異なるタブで複数のコーディネーターをインスタンス化する方法がわかりません。
メインのアプリコーディネータークラスは次のとおりです...
protocol UINavigationControllerType: class {
func pushViewController(_ viewController: UIViewController, animated: Bool)
func popViewController(animated: Bool) -> UIViewController?
}
protocol Coordinator: class {
func start()
}
final class AppCoordinator: Coordinator {
// MARK: - Properties
var managedObjectContext: NSManagedObjectContext!
var coordinators = [String : Coordinator]()
var tabController: UITabBarController?
// MARK: - Object Lifecycle
init(moc: NSManagedObjectContext, tabController: UITabBarController) {
self.managedObjectContext = moc
self.tabController = tabController
}
// MARK: - Coordinator
func start() {
guard let tabController = tabController else {return}
let profileNavigationController = NavigationController()
profileNavigationController.tabBarItem = UITabBarItem(title: "Profile", image: UIImage(named: "profileUnselected"), selectedImage: UIImage(named: "profileSelected"))
let plansNavigationController = NavigationController()
plansNavigationController.tabBarItem = UITabBarItem(title: "Plans", image: UIImage(named: "plansUnselected"), selectedImage: UIImage(named: "plansSelected"))
tabController.viewControllers = [profileNavigationController, plansNavigationController]
tabController.selectedViewController = profileNavigationController
let profileCoordinator = ProfileCoordinator(navigationController: profileNavigationController)
profileCoordinator.managedObjectContext = managedObjectContext
coordinators["profileCoordinator"] = profileCoordinator
profileCoordinator.delegate = self
profileCoordinator.start()
}
}
// MARK: - ProfileCoordinatorDelegate
extension AppCoordinator: ProfileCoordinatorDelegate {}
では、タブが選択されているときに、現在のコーディネーター(ProfileCoordinator)からPlansCoordinatorにどのように移動しますか?
私のコーディネーターの構造はあなたのものとは異なりますが、あなたに役立つかもしれません。私の場合、コーディネータープロトコルには、そのコーディネーターのViewControllerを指すrootViewController
プロパティがあります。
その後、私のAppCoordinator
はTabCoordinator
を永続化しますが、これは次のようになります(実際のコードでは、永続化されたコーディネーターはNavigationCoordinators
であり、NavigationControllersを保持する特別なコーディネーターです。例ViewControllerを追加し、メモリ管理機能を削除してわかりやすくしました。)
final class TabCoordinator: NSObject, Coordinator {
var rootViewController: UIViewController {
return tabController
}
let tabController: UITabBarController
let homeCoordinator: HomeCoordinator
let historyCoordinator: HistoryCoordinator
let profileCoordinator: ProfileCoordinator
var coordinators: [Coordinator] {
return [homeCoordinator, historyCoordinator, profileCoordinator]
}
init(client: HTTPClient, persistence: Persistence) {
tabController = UITabBarController()
homeCoordinator = HomeCoordinator(client: client, persistence: persistence)
historyCoordinator = HistoryCoordinator(client: client, persistence: persistence)
profileCoordinator = ProfileCoordinator(client: client, persistence: persistence)
var controllers: [UIViewController] = []
let homeViewController = homeCoordinator.rootViewController
homeViewController.tabBarItem = UITabBarItem(title: Localization.homeTab.string, image: Asset.iconMenuRecharge.image, selectedImage: Asset.iconMenuRechargeActivated.image)
let historyViewController = historyCoordinator.rootViewController
historyViewController.tabBarItem = UITabBarItem(title: Localization.walletTab.string, image: Asset.iconMenuWallet.image, selectedImage: Asset.iconMenuWalletActivated.image)
let profileViewController = profileCoordinator.rootViewController
profileViewController.tabBarItem = UITabBarItem(title: Localization.profileTab.string, image: Asset.iconMenuProfile.image, selectedImage: Asset.iconMenuProfileActivated.image)
super.init()
controllers.append(homeViewController)
controllers.append(historyViewController)
controllers.append(profileViewController)
tabController.viewControllers = controllers
tabController.tabBar.isTranslucent = false
tabController.delegate = self
}
}
したがって、基本的に、TabBarControllerはrootViewController
がTabBarControllerであるTabCoordinatorです。 TabCoordinatorは関連するCoordinatorをインスタンス化し、それぞれのrootViewControllers
をタブに追加します。
NavigationCoordinator
の基本的な実装は次のとおりです。
class NavigationCoordinator: NSObject, Coordinator {
public var navigationController: UINavigationController
public override init() {
self.navigationController = UINavigationController()
self.navigationController.view.backgroundColor = .white
super.init()
}
public var rootViewController: UIViewController {
return navigationController
}
}
Coordinator
の基本バージョン:
public protocol Coordinator: class {
var rootViewController: UIViewController { get }
}
この質問の例を共有したいと思います。私のアプローチは少し異なり、TabCoordinator
は彼の体にすべてを含んでいません。これの代わりに、すべてのコーディネーターはコントローラーと関係を持ち、すべてのUIViewController
(Tabbarコントローラー内)には委任パターンのようなUITabBarController
参照があります。
class Coordinator {
var navigationController: UINavigationController?
var childCoordinators: [Coordinator] = [Coordinator]()
init(with navigation: UINavigationController) {
self.navigationController = navigation
}
func start() {}
}
次に、コーディネーターがいます。
ホームコーディネーター
final class HomeCoordinator: Coordinator {
var currentController: HomeController?
weak var tabController: TabController?
override init(with navigation: UINavigationController) {
super.init(with: navigation)
currentController = HomeController()
currentController?.coordinator = self
childCoordinators.append(self)
}
override func start() {
navigationController?.pushViewController(currentController ?? UIViewController(),
animated: true)
}
public func getHomeData() {
// GETTING HOME DATA
tabController?.requestFromHomeController()
}
}
コーディネーターについて
final class AboutCoordinator: Coordinator {
var currentController: AboutController?
weak var tabController: TabController?
override init(with navigation: UINavigationController) {
super.init(with: navigation)
currentController = AboutController()
currentController?.coordinator = self
childCoordinators.append(self)
}
override func start() {
navigationController?.pushViewController(currentController ?? UIViewController(),
animated: true)
}
public func getAboutData() {
// GETTING ABOUT DATA
tabController?.requestFromAboutController()
}
}
UITabBarController
final class TabController: UITabBarController {
weak var coordinator: MainTabCoordinator?
override func viewDidLoad() {
super.viewDidLoad()
let navigationController1 = UINavigationController()
let coordinator1 = HomeCoordinator(with: navigationController1)
coordinator1.tabController = self
coordinator1.currentController?.tabBarItem = UITabBarItem(title: "HOME",
image: nil,
tag: 11)
let navigationController2 = UINavigationController()
let coordinator2 = AboutCoordinator(with: navigationController2)
coordinator2.tabController = self
coordinator2.currentController?.tabBarItem = UITabBarItem(title: "ABOUT",
image: nil,
tag: 22)
viewControllers = [
coordinator1.currentController!,
coordinator2.currentController!
]
tabBar.barTintColor = UIColor.white
tabBar.isTranslucent = false
}
public func requestFromHomeController() {
print("Home Triggered the function")
coordinator?.fetchHome(with: "Simple Data",
completion: { (dictionary, error) in
print("dict from home -> ", dictionary)
})
}
public func requestFromAboutController() {
print("About Triggered the function")
coordinator?.handleAbout(with: "Simple Data",
completion: { (dictionary, error) in
print("dict from about -> ", dictionary)
})
}
}
AppDelegateからアプリを準備する
in application(_ application:UIApplication、didFinishLaunchingWithOptions関数
let appNavigationController = UINavigationController()
let tabCoordinator = MainTabCoordinator(with: appNavigationController ?? UINavigationController())
tabCoordinator.start()
window?.rootViewController = appNavigationController
これがAboutControllerです
final class AboutController: UIViewController{
weak var coordinator: AboutCoordinator?
// define a button and add its target to handleButton function
@objc private func handleButton(_ sender: UIButton) {
coordinator?.getAboutData()
}
override func viewDidLoad() {
super.viewDidLoad()
// ui settings
}
}
MainTabCoordinator
final class MainTabCoordinator: Coordinator {
var currentController: TabController?
override init(with navigation: UINavigationController) {
super.init(with: navigation)
self.currentController = TabController()
self.childCoordinators.append(self)
currentController?.coordinator = self
}
override func start() {
navigationController?.pushViewController(currentController ?? UIViewController(),
animated: true)
}
func fetchHome(with title: String, completion: @escaping (_ result: Dictionary<String,Any>, _ error: NSError?) -> ()) {
completion(["ss":"ss"], nil)
}
func handleAbout(with title: String, completion: @escaping (_ result: Dictionary<String,Any>, _ error: NSError?) -> ()) {
completion(["ss":"ss"], nil)
}
}
作業スキーマは次のようになります。
AboutController
--->トリガーされたアクション---> AboutCoordinator
---> TabBarController reference
は、アクションについてのリクエストがあります----> MainTabCoordinator
ハンドルが機能します。