2015-09-28 99 views
1

问题: 我有一个视图控制器,它包含两个变量,没有这个变量,控制器无法工作。因此,从概念上讲,这些变量是强制性的或非任意的。Swift:使用自定义参数初始化UIViewController子类

但是,我宣布它们是可选的,这导致几乎每一种方法的第一行中都有警告声明。 原因使他们可选的是:

  • 我不能够给他们合理的默认值,他们需要在初始化时从外部设置
  • 我初始化控制器storyboard?.instantiateViewControllerWithIdentifier所以没有办法(据我所知)来定义我自己的初始化器,它取得了必要的值。这显然是我最喜欢的解决方案。
  • 我不想让他们非可选只是声明,以避免运行时的问题,可能由他们来解决编译

变量声明(!):

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) 

任何想法?

+0

为什么不把它们初始化为var dataSource:MyDataSource = MyDataSource()以避免可选项 –

+0

因为它是一个通用的视图控制器,通过数据源和单元管理器的不同实现获取其特定行为,即视图控制器的每个实例获得自己的数据源/单元管理器,这是不同类别的实例。 –

+0

由于在UIViewController中没有合适的初始值设定项,所以不能从具有初始值设定项的Storyboard中实例化视图控制器。所以唯一的选择就是我的答案中的“class func”。 – mixel

回答

1

你可以写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

+0

谢谢。看起来像一个合适的解决方案。与公共初始化程序的私有覆盖一起,应该完成这项工作。 –

+0

很好的例子:) –

+0

什么初始化器,xcode给出错误,没有初始化器 –

相关问题