2015-08-19 114 views
0

我爲我的UICollectionView使用定製的UICollectionViewCell類。我必須在自定義類中使用addSubview,因爲我使用的是FirebaseUI-iOS。這是我的MessageCollectionViewCell是什麼樣子:在UICollectionViewCell中使用Storyboard中的Autolayout約束條件

import Foundation 
import UIKit 
class MessageCollectionViewCell: UICollectionViewCell { 
    @IBOutlet var messageContainerView: UIView? 
    @IBOutlet var messageText: UILabel? 
    @IBOutlet var messageDisplayName: UILabel? 
    @IBOutlet var messageUserImage: UIImageView? 
    @IBOutlet var messageUserImageOverlay: UIView? 

    override init(frame: CGRect) { 
     super.init(frame: frame) 

     // Custom initialization code for label 
     let size = self.contentView.frame.size 
     let frame = CGRectMake(0.0, 0.0, size.width, size.height) 

     self.messageContainerView = UIView(frame: frame) 
     self.messageUserImageOverlay = UIView(frame: frame) 
     self.messageText = UILabel(frame: frame) 
     self.messageDisplayName = UILabel(frame: frame) 

     self.messageContainerView!.addSubview(self.messageUserImageOverlay!) 
     self.messageContainerView!.addSubview(self.messageText!) 
     self.messageContainerView!.addSubview(self.messageDisplayName!) 
     self.contentView.addSubview(messageContainerView!) 
    } 

    required init(coder aDecoder: NSCoder) { 
     println("Init") 
     super.init(coder: aDecoder) 
    } 
} 

我有我的故事板文件,我想使用的限制,但是當我用我的addSubview約束並不習慣。無論如何,我可以使用addSubview()並仍然保持約束?我知道我可以以編程方式添加它,但我希望使用我已經在Storyboard中設置的約束條件。

+0

看起來像它與此有關:http://stackoverflow.com/questions/13224090/uicollectionview-registercell-blank-cells。看起來像https://github.com/firebase/FirebaseUI-iOS/blob/master/FirebaseUI/Implementation/FirebaseCollectionViewDataSource.m#L77導致覆蓋原型單元格。您還可以使用FirebaseCollectionViewDataSource的XIB構造函數,並且仍然有一個自定義類。這應該引入來自XIB和自動佈局的約束,比原型單元更強大。 –

回答

1

此問題是由於FirebaseUI'FirebaseCollectionViewDataSource`如何註冊它的類。我不認爲有可能像這樣實例化一個類並從XIB中獲取自動佈局屬性,但是可以通過修復原型單元格的處理來解決問題。

這裏的問題在於我們註冊了兩次單元重用標識符:一次在故事板中,一次在代碼中(FirebaseCollectionViewDataSource必須這樣做才能使單元出列)。既然我們把它叫做第二個,它就會覆蓋第一個,這意味着你的網點沒有被填充,佈局很奇怪等等。這意味着你必須設置它們,就像你使用常規子類而不是XIB一樣。你可以在這裏做的最快的事情就是使用XIB而不是原型單元格(它只是故事板中的XIB)。那麼,我們怎樣才能支持FirebaseUI +原型細胞...

簡短的回答是,目前這個功能是不可能由於UICollectionView蘋果的設計。

不像UITableView,這可以通過出隊的單元(這將返回一個實例化原型細胞,並告訴我們,reuseidentifier已經創建),就像我們在FirebaseTableViewDataSourcehere做檢查這種行爲,UICollectionView不提供類似方法,只給出了:

func dequeueReusableCellWithReuseIdentifier(_ identifier: String, 
          forIndexPath indexPath: NSIndexPath!) -> AnyObject 

鑑於此方法需要一個indexPath,因爲它返回一個非空對象,它將當我們嘗試讀取在初始化(任意對象拋出NSInternalInconsistencyException因爲不存在可供讀取的項目)。此外,似乎沒有任何方式通過編程檢查reuseIdentifier是否正在使用中。這給我們留下了幾個選項:

  1. 建議人們不要使用原型細胞,而不是做定製子類或XIBs和故事板和原型細胞覺得有點更脆(大多爲這樣的原因)掛鉤他們,但。絕對有它們的易用性。
  2. -registerClass: forReuseIdentifier:召喚出來的FirebaseCollectionViewDataSource,儘管這意味着FirebaseTableViewDataSource也應得到(即使它可以工作)改變,使開發人員調用這個(或不使用一個Storyboard的情況下)。
  3. 添加參數爲故事板初始化調用其仍將保留reuseIdentifier出列細胞,但沒有註冊類。
  4. 試着將細胞出隊,趕上NSException,註冊課程並重試。這可以起作用,但它會拋出異常,並在runloop中添加更多代碼(我們必須用try-catch包裝調用,我們知道最多隻會失敗一次)。

我個人偏好是1,但原型單元的價值主張足夠高,3可能是這個庫的最佳選擇。我寧願不做2,因爲電池註冊是一個足夠困難的問題。現在,我建議使用XIB而不是原型單元,或者等待我們選擇上述解決方案之一(我們可以很快推送一個版本來解決問題)。