首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift:如何使用X协调人从子协调器中设置根视图控制器?

Swift:如何使用X协调人从子协调器中设置根视图控制器?
EN

Stack Overflow用户
提问于 2020-06-01 06:58:28
回答 1查看 2K关注 0票数 3

我试图了解如何使用XCoordinator从子协调器中设置根视图控制器。

我有一个应用程序代表,运行应用程序协调程序。

我的模式是:

AppDelegate -应用程序协调器-主菜单协调器-游戏调试器

(见图)

应用程序协调器不应该直接了解特定的视图控制器,因为我认为视图控制器应该由它们各自的协调器管理。

因此,应用程序协调器应该管理协调器之间的流,并设置一个根,初始协调器。

遗憾的是,屏幕是空白的,并不断抱怨我不能“推送导航控制器是不支持的”。

但是,如果我在应用程序协调器中直接实例化视图控制器,就可以了,我不知道为什么。

代码语言:javascript
复制
// AppCoordinator
enum AppRoute: Route {
    case mainmenu
    case game
}

class AppCoordinator: NavigationCoordinator<AppRoute> {

    init() {
        super.init(initialRoute: .mainmenu)
    }

    // MARK: Overrides
    override func prepareTransition(for route: AppRoute) -> NavigationTransition {
        let router = MainMenuCoordinator().strongRouter
        return .push(router)
    }
}

这将启动MainMenu协调员的初始视图控制器。

代码语言:javascript
复制
enum MainMenuRoute: Route {
    case mainmenu
}

// MainMenuCoordinator
class MainMenuCoordinator: NavigationCoordinator<MainMenuRoute> {

    init() {
        super.init(initialRoute: .mainmenu)
    }


    override func prepareTransition(for route: MainMenuRoute) -> NavigationTransition {
        print ("route: \(route as Any)")

            let vc = MainMenuViewController.instantiate(.main)
            return .push(vc)
     }
}

但这会返回一个空白屏幕,并抱怨不支持推送。

但是,如果我移动这个代码

代码语言:javascript
复制
let vc = MainMenuViewController.instantiate(.main)
return .push(vc)

致副协调员

就像这样:

代码语言:javascript
复制
// MARK: AppCoordinator Overrides
override func prepareTransition(for route: AppRoute) -> NavigationTransition {
    let vc = MainMenuViewController.instantiate(.main)
    return .push(vc)
}

很好。显示了一个屏幕--但是主菜单协调器不再被“跟随”。

我想知道

我很感谢你能提供的任何帮助。谢谢

// Edit:在给出的答案之后,我又尝试将父协调器的引用传递给子协调器。

我希望mainmenucoordinator使用它自己的路由集合;我不想只依赖于AppRoutes中定义的任何路由。

所以我的应用程序协调器有以下几条路线:

代码语言:javascript
复制
enum AppRoute: Route {
    case mainmenu
    case game
}

class AppCoordinator: NavigationCoordinator<AppRoute> {

init() {
    let defaultRoute: AppRoute = .mainmenu
    super.init(initialRoute: defaultRoute)
    self.rootViewController.view.backgroundColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
}

}

我的主要协调员有以下几条路线:

代码语言:javascript
复制
enum MainMenuRoute: Route {
    case mainmenu
    case selectPlayer
    case playgame
}

class MainMenuCoordinator: NavigationCoordinator<MainMenuRoute> {

    // For my child coordinators, keep a strong reference to parent
    private var router: StrongRouter<AppRoute>?
/// ...
}

当我加入它的时候,我设置了父母。

代码语言:javascript
复制
// MainMenuCoordinator: Init
  convenience init(router: StrongRouter<AppRoute>) {
        self.init(initialRoute: .mainmenu)
    }

但是现在它不再使用我为MainMenuCoordinator定义的任何路由,而是使用AppRoute

示例:

尝试在MainMenuCoordinator.prepareTransition中设置路由器

代码语言:javascript
复制
override func prepareTransition(for route: MainMenuRoute) -> NavigationTransition {
        print ("route: \(route as Any)")

        switch route {
        case .mainmenu:
            let vc = MainMenuViewController.instantiate(.main)
            vc.router = strongRouter
            return .push(vc)
        // ....
      }
}

主菜单视图控制器保存对以下内容的引用:

代码语言:javascript
复制
class MainMenuViewController: UIViewController, Storyboarded {

    // MARK: - Stored properties
    var router: UnownedRouter<MainMenuRoute>!
}

对于这些编辑,根视图控制器现在是白色的;但是记录器仍然抱怨我不能推送视图控制器。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-01 18:45:05

我是这样做的:

代码语言:javascript
复制
class MainCoordinator: NavigationCoordinator<ApplicationRoute> {

    convenience init() {
        var defaultRoute: ApplicationRoute = .showAuthentification
        if ApplicationSettings.shared.isLoggedIn {
            defaultRoute = .showApplicationRoot
        }

        self.init(defaultRoute: defaultRoute)
        self.rootViewController.view.backgroundColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
    }

    override func prepareTransition(for route: ApplicationRoute) -> NavigationTransition {
        switch route {
            case .showAuthentification:
                return .multiple(.dismissToRoot(animation: .fadeInstant),
                                 .presentFullScreen(AuthentificationCoordinator(router: strongRouter),
                                                    animation: .fadeInstant))

            case .showApplicationRoot:
                return .multiple(.dismissToRoot(animation: .fadeInstant),
                                 .presentFullScreen(TabControllerCoordinator(router: strongRouter),
                                                    animation: .fadeInstant))

        }
    }
}

在一个儿童协调员中:

代码语言:javascript
复制
class AuthentificationCoordinator: NavigationCoordinator<AuthentificationRoute> {
    // For my child coordinators I keep a strong reference to the parent, so I can use it later
    private var router: StrongRouter<SMCApplicationRoute>?

    convenience init(router: StrongRouter<SMCApplicationRoute>) {
        self.init(defaultRoute: .initial)
        self.router = router
    }

    override func prepareTransition(for route: AuthentificationRoute) -> NavigationTransition {
        switch route {
        case .initial:
            let initialVC = LandingPageViewController.loadFromXIB(type: LandingPageViewController.self)
            initialVC.router = strongRouter
            return .push(initialVC, animation: .fade)

        case .showLogin:
            let loginVC = LoginViewController.loadFromXIB(type: LoginViewController.self)
            loginVC.router = strongRouter
            return .push(loginVC, animation: .fade)

        case .showHome:
            // Here I trigger the other route from MainCoordinator. If I log in, the AuthentificationCoordinator will get destroyed, with all the child coordinators with root controllers
            return .trigger(SMCApplicationRoute.showApplicationRoot, on: router!)
        }
    }
}

我认为有更好的解决办法,但我发现这是有效的。如果代码不是自我解释的,请告诉我;)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62127114

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档