Swift UICollectionViewCell寄存器类失败,但寄存器nib工作

Swift UICollectionViewCell寄存器类失败,但寄存器nib工作,swift,uicollectionview,uicollectionviewcell,Swift,Uicollectionview,Uicollectionviewcell,为myUICollectionViewController创建自定义的UICollectionViewCell,它通过注册nib来工作;但是,未能按类注册 使用registerClass()失败 按类注册似乎是正确的-它生成,但在运行时从UIView中展开可选元素时引发异常。没有参考插座,它运行;但是,集合视图中不显示任何单元格 collectionView?.registerClass(MyCollectionViewCell.self,

为my
UICollectionViewController
创建自定义的
UICollectionViewCell
,它通过注册nib来工作;但是,未能按类注册

使用registerClass()失败

按类注册似乎是正确的-它生成,但在运行时从UIView中展开可选元素时引发异常。没有参考插座,它运行;但是,集合视图中不显示任何单元格

collectionView?.registerClass(MyCollectionViewCell.self, 
                              forCellWithReuseIdentifier: "myCell")
显然,视图没有加载;但是,我认为设置单元格的自定义类将提供必要的链接

使用registernb()-works

通过nib注册是可行的,因为它显式地加载视图

let nib = UINib(nibName: "MyCollectionViewCell", bundle: nil)
collectionView?.registerNib(nib, forCellWithReuseIdentifier: "myCell")
这里显式引用视图,并为视图设置自定义类;然而,这似乎有点不对劲

样本项目 在示例项目中隔离问题,下面是要复制的视图和代码;或者,这个项目是

Main.storyboard

我的主情节提要初始视图控制器是一个
UICollectionViewController
子类,分类为
MyCollectionViewController

MyCollectionViewController.swift

显示按nib注册和按类注册:

import UIKit

class MyCollectionViewController: UICollectionViewController {

    var data = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()

        data = ["a", "b", "c"]

        // This works, by nib
        let nib = UINib(nibName: "MyCollectionViewCell", bundle: nil)
        collectionView?.registerNib(nib, forCellWithReuseIdentifier: "myCell")

        // This fails, by class
        //collectionView?.registerClass(MyCollectionViewCell.self, forCellWithReuseIdentifier: "myCell")
    }

    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return data.count
    }

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("myCell", forIndexPath: indexPath) as! MyCollectionViewCell

        cell.title.text = data[indexPath.row]

        return cell
    }

}
MyCollectionViewCell.xib

视图是一个
UICollectionViewCell
子类,分类为
MyCollectionViewCell
,带有
UILabel

在我的nib中,集合可重用视图标识符已设置为:
myCell

MyCollectionViewCell.swift

定义类,并在标签上有一个
IBOutlet

import UIKit

class MyCollectionViewCell: UICollectionViewCell {

    @IBOutlet weak var title: UILabel!

}
使用nib,执行显示为:

为什么我不能按类注册
UICollectionViewCell

同样,对于原型单元是否需要保留在主故事板集合视图控制器上,我有点模糊。在这里,我没有定义任何可重用的视图标识符。

我看到了这个链接

如果单元类是用代码编写的,则使用UICollectionView的registerClass:方法执行注册。例如: [self.myCollectionView注册表类:[MyCollectionViewCell类]forCellWithReuseIdentifier:@“MYCELL”]; 如果单元格包含在Interface Builder NIB文件中,则使用registerNib:方法

所以你的收集单元是用nib创建的,你应该用nib注册。如果您的单元格完全用代码编写,则需要向类注册


希望有帮助。

实际上,如果您在脚本中注册该类并在脚本中为其提供重用标识符,那么您不应该在代码中注册它的类或nib

这里失败的不是collectionview。自定义类包含的标签隐式展开可选,定义如下:

@IBOutlet weak var title: UILabel!
这就是失败的原因。你在哪里实例化它?你的数据源方法会被调用,就像这样

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("myCell", forIndexPath: indexPath) as! MyCollectionViewCell

    cell.title.text = data[indexPath.row]

    return cell
}
您正在尝试将文本设置为该属性title,该属性为零,这会使您的应用程序崩溃

如果在应该修复的代码中使用标签,请在collectionViewinitWithFrame:方法中初始化标签

在代码中使用时,将此代码添加到单元格子类中

class MyCollectionViewCell: UICollectionViewCell {

    @IBOutlet weak var title: UILabel!

    override init(frame: CGRect) {
        super.init(frame: frame)
        let title = UILabel(frame: CGRectZero)
        title.translatesAutoresizingMaskIntoConstraints = false;
        contentView.addSubview(title)
        self.title = title

        title.topAnchor.constraintEqualToAnchor(contentView.topAnchor).active = true
        title.leftAnchor.constraintEqualToAnchor(contentView.leftAnchor).active = true
        self.backgroundColor = UIColor.redColor()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

如果从nib文件定义单元,系统将选择nib文件来实例化单元。如果没有定义任何nib文件(完全由代码维护),则单元格应该由

- initWithStyle:reuseIdentifier:
方法。 当你使用

- dequeueReusableCellWithIdentifier:
如果使用nib维护视图,将调用方法
-awakeFromNib
; 否则


将被调用。

不是-我不想使用原型单元,因为没有办法对其进行子类化。此单元格仅提供大小,除非我缺少某些内容。
title
只是视图实例化的
UILabel
的一个出口,除非我缺少某些内容。不过,这仍然不会链接视图,因为nib中定义了
myCell
。此操作失败的原因是:“无法将标识符为myCell的种类:UICollectionElementKindCell的视图出列-必须为标识符注册nib或类,或在情节提要中连接原型单元”`-非常感谢您的见解,不过,谢谢。您的属性是否具有@IBOutlet并不重要。让nib知道视图与代码中的属性有某种连接只是一个限定符。如果您正在使用代码注册类,那么请像我上面所做的那样使用代码。或者,如果您使用nib,那么您的代码应该可以正常工作,无需任何修改。您在哪里注册非代码中的类??在nib文件或故事板中的哪个位置?啊哈-您的解决方案工作得非常好。这提供了一个使用
registerClass
工作的代码实现。很抱歉造成混淆-这是正确的。
- initWithStyle:reuseIdentifier: