Подключенные 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 совпадают в раскадровках и коде?