【问题标题】:Subclassing UICollectionViewCell and initialising from xib子类化 UICollectionViewCell 并从 xib 初始化
【发布时间】:2015-06-19 07:50:12
【问题描述】:

我正在像这样注册单元格:

collectionView!.registerNib(UINib(nibName: "ItemCell", bundle: nil), forCellWithReuseIdentifier: "ItemCellIdentifier")

并像这样访问它:

let cell = collectionView.dequeueReusableCellWithReuseIdentifier("ItemCellIdentifier", forIndexPath: indexPath) as! ItemCell

ItemCell 是 UICollectionViewCell 的子类:

class ItemCell: UICollectionViewCell {

    @IBOutlet weak var itemImage: UIImageView!
    @IBOutlet weak var itemImageDescription: UILabel!

    //creation from nib requires this method to be overridden
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

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

最后我有一个带有类 ItemCell 的 UICollectionViewCell 的 xib。

我不断收到错误:

-[UICollectionView 中的断言失败 _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:], /SourceCache/UIKit/UIKit-3347.44.2/UICollectionView.m:3443.

崩溃就在这一行:

let cell = collectionView.dequeueReusableCellWithReuseIdentifier("ItemCellIdentifier", forIndexPath: indexPath) as! ItemCell

编辑

collectionView!.registerNib(UINib(nibName: "ItemCell", bundle: nil), forCellWithReuseIdentifier: "ItemCellIdentifier")

被调用

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)

}

包含在:

class CollectionCell : UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegate {

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    你在哪里打电话给registerNib

    我复制了设置以匹配我从你那里得知的内容。

    这对我有用,没有错误:

    import UIKit
    
    class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
    
        var model:[String] = []
    
        @IBOutlet weak var collectionView: UICollectionView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // just a simple test model ...
            for index in 1...100 {
                model.append("\(index)")
            }
    
            // register the nib
            collectionView.registerNib(UINib(nibName: "ItemCell", bundle: nil), forCellWithReuseIdentifier: "ItemCell")
    
            // this is just a test layout
            var layout = UICollectionViewFlowLayout()
            layout.itemSize = CGSize(width:200.0,height:200.0)
            layout.scrollDirection = UICollectionViewScrollDirection.Vertical
            self.collectionView.collectionViewLayout = layout
            self.collectionView.delegate = self;
            self.collectionView.dataSource = self;
            self.collectionView.reloadData()
        }
    
        // MARK: -  UICollectionViewDataSource
        func collectionView(collectionView: UICollectionView,
            numberOfItemsInSection section: Int) -> Int{
                return model.count
        }
    
        func collectionView(collectionView: UICollectionView,
            cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell{
                var cell:UICollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("ItemCell", forIndexPath: indexPath) as! UICollectionViewCell
                return cell
        }
    }
    

    【讨论】:

    • Alessandro,您的编辑说您正在从自定义 UITableViewCell 的初始化程序内部调用 registerNib ?对不起,这根本没有任何意义。 registerNib 应该在 viewDidLoadUIViewController 方法上调用。
    • 它实际上是一个 UITableViewCell,里面有一个集合视图
    • UICollectionView 应该只显示 UICollectionViewCell 的。我建议阅读有关 UICollectionView 的文档,然后完全重新制定您的设置。你所做的事情没有什么意义,代码质量很差,难怪你会出错。
    • 在您的示例中,您正在做同样的事情。您正在从 UIViewController 添加一个 collectionView。我从 UITableViewCell 中添加它
    • 一个 UIViewController 是一个控制器。 UITableViewCell 是一个视图。在 MVC 范式中,这两件事非常不同,我无法解释这一点,请阅读 MVC 以了解差异。在任何情况下,很难从您显示的代码中说出来,但是如果您正在做的是在 UITableViewCell 中添加一个 UICollectionView 来满足一些复杂的布局需求,那么调用 registerNib 的正确位置是 UIViewController 中的 viewDidLoad 方法,它持有界面视图。单元格的 init() 方法根本无法正常工作(如果确实如此,也不应该尝试)。
    【解决方案2】:

    尝试在主包中搜索

    collectionView!.registerNib(UINib(nibName: "ItemCell", bundle: NSBundle.mainBundle()), forCellWithReuseIdentifier: "ItemCellIdentifier")
    

    【讨论】:

      【解决方案3】:

      崩溃是因为向下转换失败。而不是使用强制形式作为!使用条件 as?

      尝试其他方式来注册单元格:

      ViewDidLoad

      collectionView.registerClass(ItemCell.self,forCellWithReuseIdentifier:"ItemCellIdentifier")
      

      cellForItemAtIndexPath

      func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath:NSIndexPath)->UICollectionViewCell
      {
            var  cell = collectionView.dequeueReusableCellWithReuseIdentifier("ItemCellIdentifier", forIndexPath: indexPath) as ItemCell
          cell.titleLabel.text="cellText"
          return cell
      }
      

      【讨论】:

      • 编译器强制我使用 as!。它说“AnyObject”不能转换为“itemCell”
      • 我已经编辑了我的答案。我的编译器没有强迫我使用 as!
      • 为什么要覆盖 ItemCell 中的初始化程序?除了调用 super 之外,您实际上并没有在任何一个初始化程序中做任何事情,因此您不需要实现任何一个初始化程序!如果你不重写任何指定的初始化器,你继承你的超类的所有指定的初始化器。
      猜你喜欢
      • 2021-12-14
      • 2013-05-08
      • 1970-01-01
      • 1970-01-01
      • 2015-12-26
      • 1970-01-01
      • 1970-01-01
      • 2023-02-18
      • 2011-01-15
      相关资源
      最近更新 更多