Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift:使用自定义参数初始化UIViewController子类_Ios_Swift_Initialization - Fatal编程技术网

Ios Swift:使用自定义参数初始化UIViewController子类

Ios Swift:使用自定义参数初始化UIViewController子类,ios,swift,initialization,Ios,Swift,Initialization,问题是: 我有一个视图控制器,它包含两个变量,没有这两个变量,控制器就无法工作。因此,从概念上讲,这些变量是强制性的或非选择性的 然而,我声明它们是可选的,这导致几乎每个方法的第一行都有一个guard语句。 使其成为可选的原因是: 我无法给它们合理的默认值,它们需要在初始化期间从外部设置 我使用storyboard?初始化控制器。instanceeviewcontrollerwhiteIdentifier,因此(据我所知)无法定义我自己的初始值设定项,该初始值设定项采用必要的值。这显然是我最喜

问题是: 我有一个视图控制器,它包含两个变量,没有这两个变量,控制器就无法工作。因此,从概念上讲,这些变量是强制性的或非选择性的

然而,我声明它们是可选的,这导致几乎每个方法的第一行都有一个guard语句。 使其成为可选的原因是:

  • 我无法给它们合理的默认值,它们需要在初始化期间从外部设置
  • 我使用
    storyboard?初始化控制器。instanceeviewcontrollerwhiteIdentifier
    ,因此(据我所知)无法定义我自己的初始值设定项,该初始值设定项采用必要的值。这显然是我最喜欢的解决方案
  • 我不想仅仅通过声明(!)使它们成为非可选的,以避免运行时问题,这些问题可以通过编译器解决
变量声明:

    var dataSource : MyDataSource?
    var cellAndHeaderManager: MyCellAndHeaderManager?
典型方法开始:

    guard let cellAndHeaderManager = cellAndHeaderManager else {return UICollectionReusableView()}
    let header = cellAndHeaderManager.headerForSection(collectionView, indexPath: indexPath)
    guard let dataSource = dataSource else {return header}
初始化:

     if let newController = storyboard?.instantiateViewControllerWithIdentifier("MyViewController") as? MyCollectionViewController {
            newController.dataSource = dataSource
            newController = cellAndHeaderManager
        }
我想做的是:

newController = MyCollectionViewController(dataSource, cellAndHeaderManager)

有什么想法吗?

您可以为视图控制器编写
class func

class MyViewController {
    // ...
    class func instantiate(dataSource: MyDataSource, cellAndHeaderManager: MyCellAndHeaderManager) -> MyViewController {
        let vc = UIStoryboard(name: "Storyboard", bundle: nil).instantiateViewControllerWithIdentifier("MyViewController") as! MyViewController
        vc.dataSource = dataSource
        vc.cellAndHeaderManager = cellAndHeaderManager
        return vc
    }
}
因此,您可以使用以下方法对其进行实例化:

let vc = MyViewController.instantiate(dataSource: dataSource, cellAndHeaderManager: cellAndHeaderManager)

您不能使用初始值设定项从情节提要实例化视图控制器,因为在
UIViewController

中没有合适的初始值设定项,为什么不在var-dataSource:MyDataSource=MyDataSource()中初始化它们呢为了避免选择,因为它是一个通用视图控制器,通过不同的数据源和单元管理器实现其特定行为,即视图控制器的每个实例都有自己的数据源/单元管理器,这些是不同类的实例。您不能使用初始值设定项从序列图像板实例化视图控制器,因为UIViewController中没有合适的初始值设定项。因此,唯一的选择是
class func
,就像我的回答一样。有人否决了这个问题以及@mixel的好答案,没有留下任何评论。。。这很有帮助!谢谢看起来是一个合适的解决方案。加上对公共初始值设定项的私有重写,应该可以完成这项工作initializers@SudhanshuGupta实施它们。只要在他们的体内调用
super.init(…)
。谢谢@mixel会尝试的