2015-09-28 86 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給出錯誤,沒有初始化器 –

相關問題