为我的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
:
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
:
在我的笔尖中,集合可重用视图标识符已设置为:myCell
:
MyCollectionViewCell.swift
定义类,标签为IBOutlet
:
import UIKit
class MyCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var title: UILabel!
}
使用nib,执行显示为:
为什么我不能按班级注册UICollectionViewCell
?
同样,关于原型单元是否需要保留在主故事板集合视图控制器上,我有点模糊。在那里,我没有定义任何可重用的视图标识符。
答案 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:
将被召唤。