Подключенные IBOutlets не инициализируются
Я реализовал собственный класс UICollectionViewCell
в Swift, создал раскадровку с UICollectionViewCotroller, назначил свой собственный класс контроллера, пользовательский класс ячеек, идентификатор ячейки и т.д.... В основном все, что необходимо для работы UICollectionViewController.
В прототипе ячейки раскадровки я добавил несколько представлений и связал их как IBOutlets с моим собственным классом ячеек:
![enter image description here]()
здесь мои IBOutlets в коде (как видите, они подключены):
![enter image description here]()
Я также зарегистрировал собственный класс ячеек в моем контроллере:
self.collectionView.registerClass(MyCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
Когда я деактивирую свою ячейку в коде, она возвращает ячейку моего пользовательского типа, но оба IBOutlets не инициализируются (равно nil
)
let cell = collectionView?.dequeueReusableCellWithReuseIdentifier(reuseIdentifier,
forIndexPath: indexPath) as MyCollectionViewCell
if let path = indexPath {
// Crash here as imageView is nil
cell.imageView.image = imagesArray[path.item]
}
Crashlog:
fatal error: unexpectedly found nil while unwrapping an Optional value
если я поставил точку останова в выражении if
выше и сделать po cell
У меня есть этот вывод:
(lldb) po cell
0x00007fa799f4cdf0
{
UIKit.UICollectionViewCell = {
UIKit.UICollectionReusableView = {
UIKit.UIView = {
UIKit.UIResponder = {
ObjectiveC.NSObject = {}
}
}
}
}
selectionView = nil
imageView = nil
}
Любые идеи, почему IBOutlets не инициализируются?
Ответы
Ответ 1
У меня была такая же проблема, начиная с Beta5, хотя с xib не с раскадрой.
В случае xib это проблема с
init(nibName: nil, bundle: nil)
не собирает имя файла xib по умолчанию. Когда я перешел на явное имя nibName
init(nibName: "MyClass", bundle: nil)
то он снова начал работать. Может ли та же проблема с раскадрой - если есть способ заставить имя раскадровки, я бы попробовал это.
Ответ 2
Это происходит потому, что IBOutlets подключаются позже, после завершения initWithCoder
.
Чтобы настроить свои элементы управления после их подключения, вы можете переопределить - applyLayoutAttributes:
в подклассе UIColletionViewCell
.
override func applyLayoutAttributes(layoutAttributes: UICollectionViewLayoutAttributes) {
setupControls()
}
В соответствии с документацией это пустой метод, предназначенный для переопределения, чтобы применить к представлению собственные атрибуты макета. Звучит правильно.
Ответ 3
Ну, я также столкнулся с этой проблемой, и мои проблемы решаются путем комментирования Register api представления коллекции как следующий фрагмент кода. Я считал, что, когда мы используем раскадровку. и там мы предоставили всю информацию, такую как (класс, выходы и идентификатор). поэтому раскадровка справляется со всем этим.
func configureCollectionView(isNib:Bool = false)
{
if isNib
{
//collectionView.register(UINib(nibName: "GalleryCell", bundle:nil), forCellWithReuseIdentifier: identifier)
}
else
{
//collectionView.register(PhotoCell.self,forCellWithReuseIdentifier:identifier);
}
}
Ответ 4
Если это бета-версия 4 или 5, и я думаю, что это основано на том, что IBOutlets являются необязательными, у вас есть initWithCoder, переопределенный в классе? Даже тот, кто ничего не делает, кроме вызова супер? Это может быть вашей проблемой.
Изменить: вы пытались убедиться, что все элементы reuseIdentifiers совпадают в раскадровках и коде?