Загрузите экран из контроллера вида - PullRequest
1 голос
/ 24 апреля 2020

Я новичок в Swift / программировании в целом и пытаюсь освоиться с идеей координаторов. Извините, что просто выгрузил код, но я только учусь ... спасибо за любую помощь.

Моя цель - запустить это приложение с моим ViewController, отображаемым на экране, и этим видом, чтобы иметь две кнопки для go, чтобы два других представления.

Я определил следующие протоколы.

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
    }
}

Затем я создал свой главный координатор

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 в качестве имени класса.

Все, что я получаю, это полный черный экран, когда я запускаю код ... для меня это не имеет смысла.

1 Ответ

0 голосов
/ 24 апреля 2020

Несколько вещей здесь не так. Это нормально, так как SceneDelegate.swift был добавлен недавно.

Ваша главная проблема заключается в том, что в willConnectTo вашего SceneDelegate ваш if let window = self.window равен nil , поэтому остальная часть вашего внутреннего кода не будет выполнена, что приведет к черному экрану.

Чтобы заставить шаблон Coordinator работать с раскадровкой в ​​SceneDelegate.swift, добавьте эти 2 свойства и замените 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
    }

Наконец, тело функции didFinishLaunchingWithOptions вашего AppDelegate.swift ничего не нужно, кроме возврата true для реализации шаблона Coordinator

Не стесняйтесь использовать это как ссылку: https://github.com/SamuelFolledo/NewsApp/blob/646a005e1be9b90a4c63cb99bf92d5b2be6691cc/NewsApp/SceneDelegate.swift

...