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

时间:2015-10-28 16:36:51

标签: swift uicollectionview uicollectionviewcell

为我的UICollectionViewCell创建自定义UICollectionViewController,它通过注册笔尖来工作;但是,没有按班级注册。

使用registerClass() - 失败

按类注册似乎是正确的 - 它构建,但在运行时抛出异常,从UIView中解开可选元素。没有引用插座,它运行;但是,集合视图中不会出现单元格。

collectionView?.registerClass(MyCollectionViewCell.self, 
                              forCellWithReuseIdentifier: "myCell")

显然没有加载视图;但是,我认为设置单元格的自定义类将提供必要的链接。

使用registerNib() - 工作

通过nib注册工作,这在显式加载视图时是有意义的。

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

此处显式引用视图,并为视图设置自定义类;然而,关于这一点似乎是错误的。

示例项目

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

Main.storyboard

我的主要故事板初始视图控制器是UICollectionViewController子类为MyCollectionViewController

UICollectionViewController

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

MyCollectionViewCell

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

MyCollectionViewCell-identifier

MyCollectionViewCell.swift

定义类,标签为IBOutlet

import UIKit

class MyCollectionViewCell: UICollectionViewCell {

    @IBOutlet weak var title: UILabel!

}

使用nib,执行显示为:

iphone-4s

为什么我不能按班级注册UICollectionViewCell

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

4 个答案:

答案 0 :(得分:16)

我看到此链接Overview Collection View

  

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

所以你的集合单元用nib创建,你应该用nib注册。如果您的单元格完全用代码编写,则需要在课程中注册。

希望得到这个帮助。

答案 1 :(得分:2)

实际上,如果你在故事板中注册了类并在那里给它一个重用标识符,那么你不应该在代码中注册它的类它的nib。

答案 2 :(得分:1)

这里没有失败的集合视图。您自定义类包含标签,该标签是隐式展开的可选定义为

@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
}

在那里,您尝试将文字设置为此属性标题,这是nil,这会导致您的应用崩溃。

如果您在应该修复的代码中使用它,请在collectionView initWithFrame:方法中初始化您的标签。

在代码中使用

时,将此代码添加到您的单元子类中
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")
    }

}

答案 3 :(得分:1)

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

初始化
- initWithStyle:reuseIdentifier:

方法。 当你使用

- dequeueReusableCellWithIdentifier:

如果使用nib维护视图,将调用方法- awakeFromNib; 其他

- initWithStyle:reuseIdentifier:

将被召唤。