协调器模式 - 使用Storyboard而不是Xib

Nit*_*ish 3 xib ios xcode-storyboard swift coordinator-pattern

这是我第一次参加协调员模式.虽然我已经意识到它的重要性,但我有一个主要的问题.
我在这个模式上经历了这篇惊人的文章.事实上,我可以使用它自己构建一个演示项目.但有一点 - 建议使用Xib.并不是唯一提到故事板不能使用,但通过这些线条到文章末尾,让我想到:

强大的力量带来了巨大的责任(和限制).要使用此扩展,您需要为每个UIViewController创建单独的故事板.故事板的名称必须与UIViewController类的名称匹配.必须将此UIViewController设置为此故事板的初始UIViewController.

有人提到,在Storyboard的情况下,我们应该创建一个扩展并将其用于UIViewController:

extension MyViewController: StoryboardInstantiable {
}  
Run Code Online (Sandbox Code Playgroud)

故事板可实现:

import UIKit

protocol StoryboardInstantiable: NSObjectProtocol {
  associatedtype MyType  // 1
  static var defaultFileName: String { get }  // 2
  static func instantiateViewController(_ bundle: Bundle?) -> MyType // 3
}

extension StoryboardInstantiable where Self: UIViewController {
  static var defaultFileName: String {
    return NSStringFromClass(Self.self).components(separatedBy: ".").last!
  }

  static func instantiateViewController(_ bundle: Bundle? = nil) -> Self {
    let fileName = defaultFileName
    let sb = UIStoryboard(name: fileName, bundle: bundle)
    return sb.instantiateInitialViewController() as! Self
  }
}
Run Code Online (Sandbox Code Playgroud)

查询:

  1. 正如作者提到必须为每个创建单独的StoryboardUIViewController,如何在协调器模式中使用Xib更好的方法?
  2. 为什么我们需要为每个人创建一个单独的故事板UIViewController?我们UIViewController不能通过不链接任何UIViewController使用segues来使用故事板标识符吗?这种方式可以使用标识符调整上述扩展名并轻松实现相同.

Scr*_*ble 8

我已多次阅读该教程,并且每个View控制器使用一个协调器,这对我来说没有意义.我认为协调员的目的是将导航逻辑从视图控制器转移到可以管理整体流程的更高级别对象.

如果您想从主故事板初始化ViewControllers,请改用此协议和扩展:

import UIKit

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

extension Storyboarded where Self: UIViewController {
    static func instantiate() -> Self {
        // this pulls out "MyApp.MyViewController"
        let fullName = NSStringFromClass(self)

        // this splits by the dot and uses everything after, giving "MyViewController"
        let className = fullName.components(separatedBy: ".")[1]

        // load our storyboard
        let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)

        // instantiate a view controller with that identifier, and force cast as the type that was requested
        return storyboard.instantiateViewController(withIdentifier: className) as! Self
    }
}
Run Code Online (Sandbox Code Playgroud)

唯一的要求是它使用的每个View控制器都具有此协议,并且具有与该类同名的StoryboardID.

你可以这样使用它:

private func startBlueFlow() {
    let vc = BlueViewControllerOne.instantiate()
    vc.coordinator = self
    self.navigationController.push(vc, animated: true)
}
Run Code Online (Sandbox Code Playgroud)

免责声明:本文采用的协议也可能对您有所帮助

更新:(添加参考)

Soroush Khanlou在iOS和Redux中关于协调器模式的其他文章和教程中通常被认可和引用.他在这里有一篇文章(日期为2015年,代码为objective-c),您可能会发现这篇文章很有趣.