从视图控制器加载屏幕

Load Screen with from a View Controller

总的来说,我是 Swift/programing 的新手,我正在努力适应协调器的概念。抱歉只是转储代码,但我只是在学习..感谢您的帮助。

我的目标是启动这个应用程序时我的 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,它有三个视图控制器。每个视图控制器都有它们的 class 和它们的故事板 ID 名称作为它们的 class 名称。

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

这里有几处错误。没关系,因为 SceneDelegate.swift 是最近才添加的。

你这里的主要问题是在你的 SceneDelegate 的 willConnectTo 你的 if 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 函数体除了 return true 之外不需要任何东西来实现协调器模式

随意使用此作为参考:https://github.com/SamuelFolledo/NewsApp/blob/646a005e1be9b90a4c63cb99bf92d5b2be6691cc/NewsApp/SceneDelegate.swift