Класс регистра UICollectionViewCell терпит неудачу, но регистр работает с nib
Создание пользовательского UICollectionViewCell
для моего UICollectionViewController
, он работает, регистрируя nib; однако, не удается зарегистрировать класс.
Использование registerClass() - fail
Регистрирование по классу кажется правильным - оно строит, но генерирует исключение во время выполнения, освобождая дополнительные элементы из UIView. Без ссылок на торговые точки он работает; однако в представлении коллекции нет ячеек.
collectionView?.registerClass(MyCollectionViewCell.self,
forCellWithReuseIdentifier: "myCell")
Ясно, что представление не загружено; однако, я думаю, что настройка пользовательского класса ячейки обеспечит необходимую связь.
Использование registerNib() - работает
Регистрация с помощью nib-работ, что имеет смысл, поскольку она явно загружает представление.
let nib = UINib(nibName: "MyCollectionViewCell", bundle: nil)
collectionView?.registerNib(nib, forCellWithReuseIdentifier: "myCell")
Здесь явно ссылаются на представление, а для представления настраивается собственный класс; однако что-то об этом кажется неправильным.
Пример проекта
Изоляция проблемы в примере проекта, ниже - виды и код для репликации; или этот проект доступен в 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]()
В моем nib идентификатор коллекционного повторного просмотра был установлен: myCell
:
![MyCollectionViewCell-identifier]()
MyCollectionViewCell.swift
Определяет класс и имеет IBOutlet
для метки:
import UIKit
class MyCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var title: UILabel!
}
Используя nib, выполнение появляется как:
![iphone-4s]()
Почему я не могу зарегистрировать UICollectionViewCell
по классу?
Кроме того, я немного неясен относительно того, должна ли ячейка прототипа оставаться на главном контроллере представления коллекции раскадровки. Там я не определил идентификатор многократного использования.
Ответы
Ответ 1
Я вижу эту ссылку Обзор коллекции >
Если класс ячейки был написан в коде, регистрация выполняется с использованием метода registerClass: UICollectionView. Например: [self.myCollectionView registerClass: [Класс MyCollectionViewCell] forCellWithReuseIdentifier: @ "MYCELL" ]; В случае, если ячейка содержится в файле NIB Interface Builder, вместо этого используется метод registerNib:
Итак, ваша ячейка коллекции создаёт с помощью nib, вы должны зарегистрироваться в nib. Если ваша ячейка полностью написана в коде, вам потребуется зарегистрироваться в классе.
Надеюсь на эту помощь.
Ответ 2
Собственно, если вы зарегистрируете класс в раскадровке и дадите ему идентификатор повторного использования, то вы не должны регистрировать его класс или код в коде.
Ответ 3
Это не коллекция, которая здесь не работает. Пользовательский класс содержит ярлык, который неявно разворачивается, как опция,
@IBOutlet weak var title: UILabel!
И в этом причина неудачи. Где вы его создаете? И ваши методы datasource вызываются так, как это,
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, который равен нулю, что приводит к сбою вашего приложения.
Инициализируйте свою метку внутри метода 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")
}
}
Ответ 4
если вы определяете ячейку из файла nib, система выберет nib файл для создания экземпляра ячейки. Если не определить какой-либо файл nib (полностью поддерживаемый кодом), ячейка должна быть init с помощью
- initWithStyle:reuseIdentifier:
метод.
Когда вы используете
- dequeueReusableCellWithIdentifier:
метод - awakeFromNib
будет вызываться, если вы используете nib для сохранения представления;
else
- initWithStyle:reuseIdentifier:
будет вызываться.