私のUICollectionViewCell
用にカスタムUICollectionViewController
を作成すると、ペン先を登録することで機能します。ただし、クラスごとの登録に失敗します。
registerClass()の使用-失敗
クラスによる登録は正しいようです-ビルドしますが、実行時に例外をスローして、UIViewからオプションの要素をアンラップします。アウトレットを参照せずに実行されます。ただし、コレクションビュー内にセルは表示されません。
collectionView?.registerClass(MyCollectionViewCell.self,
forCellWithReuseIdentifier: "myCell")
明らかに、ビューはロードされていません。ただし、セルのカスタムクラスを設定すると、必要なリンクが提供されると思います。
registerNib()の使用-動作
ペン先による登録は機能します。これは、ビューを明示的にロードしているため意味があります。
let nib = UINib(nibName: "MyCollectionViewCell", bundle: nil)
collectionView?.registerNib(nib, forCellWithReuseIdentifier: "myCell")
ここでは、ビューが明示的に参照され、カスタムクラスがビューに設定されています。しかし、これについて何かが間違っているようです。
サンプルプロジェクトで問題を切り分けます。以下は、複製するビューとコードです。または、このプロジェクトは GitHubで入手可能 です。
Main.storyboard
私のメインストーリーボードの初期ビューコントローラーは、UICollectionViewController
としてサブクラス化されたMyCollectionViewController
です。
MyCollectionViewController.Swift
ペン先別とクラス別の両方の登録を表示します。
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
です。
私のペン先では、Collection Reusable View Identifierが次のように設定されています:myCell
:
MyCollectionViewCell.Swift
クラスを定義し、ラベルにIBOutlet
を付けます。
import UIKit
class MyCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var title: UILabel!
}
ペン先を使用すると、実行は次のように表示されます。
クラスごとにUICollectionViewCell
を登録できないのはなぜですか?
また、プロトタイプセルをメインのストーリーボードコレクションビューコントローラーに残す必要があるかどうかについても、少しあいまいです。そこでは、再利用可能なビュー識別子を定義していません。
このリンクが表示されます 概要コレクションビュー
セルクラスがコードで記述されている場合、登録はUICollectionViewのregisterClass:メソッドを使用して実行されます。例:[self.myCollectionView registerClass:[MyCollectionViewCell class] forCellWithReuseIdentifier:@ "MYCELL"];セルがInterfaceBuilder NIBファイル内に含まれている場合は、代わりにregisterNib:メソッドが使用されます。
したがって、コレクションセルはnibで作成するため、nibに登録する必要があります。セルが完全にコードで記述されている場合は、クラスに登録する必要があります。
この助けを願っています。
実際、ストーリーボードにクラスを登録し、そこで再利用識別子を指定する場合、そのクラスを登録するべきではありませんまたはコードのペン先です。
nibファイルからセルを定義すると、システムはnibファイルを選択してセルをインスタンス化します。 nibファイルを定義しない場合(完全にコードで維持)、セルはによって初期化される必要があります
- initWithStyle:reuseIdentifier:
方法。使用する場合
- dequeueReusableCellWithIdentifier:
メソッド- awakeFromNib
ビューを維持するためにnibを使用すると呼び出されます。そうしないと
- initWithStyle:reuseIdentifier:
と呼ばれます。
ここで失敗しているのは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これは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")
}
}