Swift: 使用自定义参数初始化 UIViewController 子类
Swift: Initialization of UIViewController subclass with custom parameters
问题:
我有一个视图控制器,它包含两个变量,没有它控制器就无法工作。因此,从概念上讲,这些变量是强制性的或非可选的。
但是,我将它们声明为可选的,这导致几乎每个方法的第一行都有 guard 语句。
将它们设为可选的原因是:
- 我无法给它们合理的默认值,它们需要在初始化期间从外部设置
- 我用
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)
有什么想法吗?
您可以为您的视图控制器编写 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)
您无法使用初始化程序从 Storyboard 实例化视图控制器,因为 UIViewController
中没有合适的初始化程序。
问题: 我有一个视图控制器,它包含两个变量,没有它控制器就无法工作。因此,从概念上讲,这些变量是强制性的或非可选的。
但是,我将它们声明为可选的,这导致几乎每个方法的第一行都有 guard 语句。 将它们设为可选的原因是:
- 我无法给它们合理的默认值,它们需要在初始化期间从外部设置
- 我用
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)
有什么想法吗?
您可以为您的视图控制器编写 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)
您无法使用初始化程序从 Storyboard 实例化视图控制器,因为 UIViewController
中没有合适的初始化程序。