2016-02-02 39 views
1

我嘗試爲UITableViewUICollectionView創建一些通用擴展來減少處理集合所需的鍋爐代碼。UICollectionView - 僅在需要時註冊筆尖

UITableView我有這樣的:

extension UITableView { 

    public func dequeueReusableCell<T:UITableViewCell>(type: T.Type) -> T { 
     let tableCell  : T 
     let cellIdentifier = String(T) 

     if let cell = self.dequeueReusableCellWithIdentifier(cellIdentifier) as? T { 
      tableCell = cell 
     } else if let _ = NSBundle(forClass: T.classForCoder()).pathForResource(cellIdentifier, ofType:"nib") { 
      self.registerNib(UINib(nibName: cellIdentifier, bundle: nil), forCellReuseIdentifier: cellIdentifier) 
      if let cell = NSBundle(forClass: T.classForCoder()).loadNibNamed(cellIdentifier, owner: nil, options: nil)[0] as? T { 
       tableCell = cell 
      } else { 
       //if anyone had better suggestion for fallback, you're welcome to comment 
       tableCell = T(style: .Default, reuseIdentifier: cellIdentifier) 
      } 
     } else { 
      tableCell = T(style: .Default, reuseIdentifier: cellIdentifier) 
     } 
     return tableCell 
    } 
} 

對於UICollectionView目前我只有這個:

extension UICollectionView { 

    public func dequeueReusableCell<T:UICollectionViewCell>(type: T.Type, indexPath: NSIndexPath) -> T { 
     let collectionCell : T 
     let cellIdentifier = String(T) 

     if let _ = NSBundle(forClass: T.classForCoder()).pathForResource(cellIdentifier, ofType:"nib") { 
      self.registerNib(UINib(nibName: cellIdentifier, bundle: nil), forCellWithReuseIdentifier: cellIdentifier) 
      collectionCell = self.dequeueReusableCellWithReuseIdentifier(cellIdentifier, forIndexPath: indexPath) as! T 
     } 
     else { 
      collectionCell = T() 
     } 
     return collectionCell 

    } 
} 

其中一期工程,但我不認爲這是整潔不夠。我想改進的只是撥打registerNib一次。不幸的是,我不能撥打dequeueReusableCellWithReuseIdentifier,因爲它會在內部斷言時失敗。我試圖玩嘗試抓住機制在斯威夫特但無濟於事。

有什麼建議嗎?

我知道我只能在VC註冊筆尖,但這不是擁有這些類別的要點。

回答

1

因此,您需要一種方法將具有特定名稱的NIB註冊狀態信息與NIB相關聯。不幸的是,每次你再次創建UINib實例,所以這個標誌不能和UINib實例關聯。例如,添加一個靜態字典,其標識符映射到UINib的擴展名(例如,通過關聯對象作爲屬性)。或者創建UINib子類,它會更好。第一次註冊NIB時設置此標誌。下次檢查這個標誌。

編輯:在WWDC 2014上有一個很棒的演講AdvancedCollectionView: Advanced User Interfaces Using Collection View。源代碼可用here。有一個AAPLShadowRegistrar類,它完全符合你的需求:維護一個可重用視圖和NIB的註冊表。

+0

如果您在一個'UICollectionView'中使用多個單元格類型,就不夠好。需要存儲啞數組,必須有更簡潔的方式來做到這一點。 – Krodak

2

下面是您可以使用的示例代碼。這個想法是傳遞一個已註冊的nib名字數組,每當你註冊你的xib時,這個名字就會被填充。你可以在你的代碼中使用它,你只需要傳入一個數組即可。這可能是一個全局數組。

你只需要在你的函數的開頭調用它,傳遞單元格ID和全局數組的名稱。

extension ViewController 
{ 
    func registerNibName(name:String, inout alreadyRegistered:[String]) 
    { 
     if !alreadyRegistered.contains(name) { 
      alreadyRegistered.append(name) 
      //self.registerNib(name) 
      print("registerNib with name \(name)") 
     } 
    } 
} 
+0

再一次,我不應該假設'UICollectionView'中使用了UICollectionViewCell'類型的固定數量,所以這對我來說還不夠。 – Krodak

+0

我已經更新了答案。請參閱,看看這是否適合你。請注意,我使用了一個示例,而不是實際的課程,但我相信你明白了。 –