简体   繁体   中英

coordinator pattern is not pushing to the NextViewController

Here is the AppDelegate.swift implementation/ configuration:

class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?
var coordinator: MainCoordinator?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    //        Fabric.with([Crashlytics.self])
    //        FirebaseApp.configure()
    let navigationController = UINavigationController()
    coordinator = MainCoordinator(navigationController: navigationController)
    coordinator?.start()
    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = navigationController
    self.window?.makeKeyAndVisible()

here is the MainCoordinator.swift

import Foundation
import UIKit

class MainCoordinator: Coordinator {
    var subCoordinators = [Coordinator]()
    var navigationController: UINavigationController

    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
    }
    func start() {
        let VC = SplashViewController.instantiate()
        VC.coordinator = self
        navigationController.pushViewController(VC, animated: false)
        NSLog("view Started")


    }

    func goToMerchandizeEntranceView() {

        let vc = MerchandizeEntranceViewController.instantiate()
        vc.coordinator = self
        navigationController.pushViewController(vc, animated: true)
    }

    func gotoMerchandizeRequestView() {

        let vc = MerchandizeRequestStatusViewController.instantiate()
        vc.coordinator = self
        navigationController.pushViewController(vc, animated: true)
    }


}

Here inside MainVC, in didselectItemAt IndexPath method of collection View should trigger to the next VC, however, VC is not triggered and displayed on secreen, " NsLog" prints the message though.. Can Anyone help me explain where i am wrong..?

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    if collectionView == menuCollectionView {
        switch indexPath.row {
        case 0:
            coordinator?.goToMerchandizeEntranceView()
            NSLog("Receiving touch")
        case 1:
            coordinator?.gotoMerchandizeRequestView()
             NSLog("Receiving touch")
        default:
            break
        }
    }
    else {

        NSLog("define action for story cell")
    }

}

Update: Since you're using storyboard you should instantiate view controller from storyboard like this:

func goToMerchandizeEntranceView() {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    if let vc = storyboard.instantiateViewController(withIdentifier: "MerchandizeEntranceViewController") as? MerchandizeEntranceViewController {
        vc.coordinator = self
        navigationController.pushViewController(vc, animated: true)
    } else {
        print("Could not instantiateViewController: MerchandizeEntranceViewController")
    }
}

func gotoMerchandizeRequestView() {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    if let vc = storyboard.instantiateViewController(withIdentifier: "MerchandizeRequestStatusViewController") as? MerchandizeRequestStatusViewController {
        vc.coordinator = self
        navigationController.pushViewController(vc, animated: true)
    } else {
        print("Could not instantiateViewController: MerchandizeEntranceViewController")
    }
}

Seems your coordinator is not initialized in MainVC . You should initialize your coordinator in viewDidLoad :

override func viewDidLoad() {
    super.viewDidLoad()
    if let navigationController = navigationController {
        coordinator = MainCoordinator(navigationController: navigationController)
    }
}

I guess, besides the view controllers instantiation mentioned above, another point that might be a source of issues is that coordinator.start is being called before the navigation controller is added to the window. I would modify the AppDelegate to be something like this:

let navigationController = UINavigationController()
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()

coordinator = MainCoordinator(navigationController: navigationController)
coordinator?.start()

Here is the AppDelegate.swift implementation/ configuration:

class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?
var coordinator: MainCoordinator?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    //        Fabric.with([Crashlytics.self])
    //        FirebaseApp.configure()
    let navigationController = UINavigationController()
    coordinator = MainCoordinator(navigationController: navigationController)
    coordinator?.start()
    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = navigationController
    self.window?.makeKeyAndVisible()

here is the MainCoordinator.swift

import Foundation
import UIKit

class MainCoordinator: Coordinator {
    var subCoordinators = [Coordinator]()
    var navigationController: UINavigationController

    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
    }
    func start() {
        let VC = SplashViewController.instantiate()
        VC.coordinator = self
        navigationController.pushViewController(VC, animated: false)
        NSLog("view Started")


    }

    func goToMerchandizeEntranceView() {

        let vc = MerchandizeEntranceViewController.instantiate()
        vc.coordinator = self
        navigationController.pushViewController(vc, animated: true)
    }

    func gotoMerchandizeRequestView() {

        let vc = MerchandizeRequestStatusViewController.instantiate()
        vc.coordinator = self
        navigationController.pushViewController(vc, animated: true)
    }


}

Here inside MainVC, in didselectItemAt IndexPath method of collection View should trigger to the next VC, however, VC is not triggered and displayed on secreen, " NsLog" prints the message though.. Can Anyone help me explain where i am wrong..?

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    if collectionView == menuCollectionView {
        switch indexPath.row {
        case 0:
            coordinator?.goToMerchandizeEntranceView()
            NSLog("Receiving touch")
        case 1:
            coordinator?.gotoMerchandizeRequestView()
             NSLog("Receiving touch")
        default:
            break
        }
    }
    else {

        NSLog("define action for story cell")
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM