1

总的来说,我是 Swift/编程的新手,我正在努力适应协调员的想法。很抱歉只是转储代码,但我只是在学习..感谢您的帮助。

我的目标是启动这个应用程序,让我的 ViewController 显示在屏幕上,并且这个视图有两个按钮可以转到其他两个视图。

我已经定义了以下协议。

import Foundation
import UIKit

protocol CoordinatorProtocol {
     var childCoordinators: [CoordinatorProtocol] { get set }
     var navigationController: UINavigationController { get set }

func start()
}

import Foundation
import UIKit

protocol StoryboardProtocol {
static func instantiate() -> Self
}

extension StoryboardProtocol where Self: UIViewController {
    static func instantiate() -> Self {
         let id = String(describing: self)
         let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
         return storyboard.instantiateViewController(withIdentifier: id) as! Self
    }
}

然后我创建了我的 MainCoordinator

import Foundation
import UIKit

class MainCoordinator: CoordinatorProtocol {

    var childCoordinators = [CoordinatorProtocol]()
    var navigationController: UINavigationController

    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
    }

    func start() {
        let vc = ViewController.instantiate()
        vc.coordinator = self
        navigationController.pushViewController(vc, animated: false)
    }

    func addDisplayOne() {
        let vc = ViewOneController.instantiate()
        vc.coordinator = self
        navigationController.pushViewController(vc, animated: true)
    }

    func addDisplayTwo() {
        let vc = ViewTwoController.instantiate()
        vc.coordinator = self
        navigationController.pushViewController(vc, animated: true)
    }
}

连同我的三个视图控制器

import UIKit

class ViewController: UIViewController, StoryboardProtocol {

    weak var coordinator: MainCoordinator?

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func oneTapped(_ sender: Any) {
        coordinator?.addDisplayTwo()
    }

    @IBAction func twoTapped(_ sender: Any) {
        coordinator?.addDisplayTwo()
    }
}

import UIKit

class ViewOneController: UIViewController, StoryboardProtocol {

    weak var coordinator: MainCoordinator?

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

import UIKit

class ViewTwoController: UIViewController, StoryboardProtocol {

    weak var coordinator: MainCoordinator?

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

然后我用以下内容更新了 appDelegate.Swift 并保留了其余的功能

var coordinator: MainCoordinator?
var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions 
    launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
    let initialViewController : UIViewController = 
        mainStoryboard.instantiateViewController(withIdentifier: "ViewController") as 
        UIViewController
    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = initialViewController
    self.window?.makeKeyAndVisible()

    return true
}

然后我用以下内容更新了 SceneDelegate.swift 并将其余部分保持不变

var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

    if let controller = UIStoryboard(name: "Main", bundle: 
    nil).instantiateViewController(withIdentifier: "ViewController") as? ViewController {
        if let window = self.window, let rootViewController = window.rootViewController {
            var currentController = rootViewController
            while let presentedController = currentController.presentedViewController {
                currentController = presentedController
            }
            currentController.present(controller, animated: true, completion: nil)
        }
    }

}

我有一个 Main.storyboard,它有三个视图控制器。每个视图控制器都有它们的类和它们的 storyboardID 名称作为它们的类名。

当我运行代码时,我得到的只是一个全黑屏......对我来说毫无意义。

4

1 回答 1

1

这里有几件事是错误的。没关系,因为最近刚刚添加了 SceneDelegate.swift。

您在这里的主要问题是,在您的 SceneDelegate 中,willConnectToif let window = self.window 是 nil,因此您内部的其余代码将不会被执行,从而导致黑屏。

为了使 Coordinator 模式与 SceneDelegate.swift 中的故事板一起工作,添加这两个属性并替换willConnectTo为以下内容:

    var coordinator: MainCoordinator?
    var window: UIWindow?


    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {        
        let navController = UINavigationController() //create navController
        coordinator = MainCoordinator(navigationController: navController) //initialize our coordinator
        coordinator?.start() //start coordinator

        guard let windowScene = (scene as? UIWindowScene) else { return }
        window = UIWindow(frame: UIScreen.main.bounds)
        window?.rootViewController = navController //make it our root
        window?.makeKeyAndVisible()
        window?.windowScene = windowScene
    }

最后,你的 AppDelegate.swift 的didFinishLaunchingWithOptions函数体不需要任何东西,只需要返回 true 来实现 Coordinator 模式

随意将其用作参考:https ://github.com/SamuelFolledo/NewsApp/blob/646a005e1be9b90a4c63cb99bf92d5b2be6691cc/NewsApp/SceneDelegate.swift

于 2020-04-24T18:53:40.253 回答