Подключенные IBOutlets не инициализированы

Я реализовал пользовательский класс UICollectionViewCell в Swift, создал раскадровку с помощью UICollectionViewCotroller, назначил свой пользовательский класс контроллера, пользовательский класс ячейки, идентификатор ячейки и т. д. В основном все, что требуется для работы UICollectionViewController.

В прототипе ячейки раскадровки я добавил несколько представлений и подключил их как IBOutlets к моему пользовательскому классу ячейки:

введите здесь описание изображения

вот мои IBOutlets в коде (как видите, они подключены): введите сюда описание изображения

Я также зарегистрировал собственный класс ячеек в своем контроллере:

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] 
    }

Крашлог:

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 не инициализируются?


person OgreSwamp    schedule 06.08.2014    source источник


Ответы (4)


У меня была такая же проблема, начиная с Beta5, хотя с xib не с раскадровкой. В случае xib, похоже, проблема с

init(nibName: nil, bundle: nil) 

не подобрать имя файла xib по умолчанию. Когда я перешел на явное nibName

init(nibName: "MyClass", bundle: nil) 

потом снова начал работать. Может ли та же проблема с раскадровкой - если есть способ принудительно указать имя раскадровки, я бы попробовал это.

person Spencer    schedule 06.08.2014

Это происходит потому, что IBOutlets подключаются позже, после завершения initWithCoder.

Чтобы настроить элементы управления после их подключения, вы можете переопределить - applyLayoutAttributes: в своем подклассе UIColletionViewCell.

override func applyLayoutAttributes(layoutAttributes: UICollectionViewLayoutAttributes) {
    setupControls()
}

Согласно документации, это пустой метод, предназначенный для переопределения, чтобы применить настраиваемые атрибуты макета к представлению. Звучит правильно.

person Kof    schedule 24.06.2015

Что ж, я также столкнулся с этой проблемой, и мои проблемы решаются путем комментирования Register api of collection view в следующем фрагменте кода. Я полагал, что поскольку мы используем раскадровку. и там мы дали всю информацию, например (класс, розетки и идентификатор). поэтому раскадровка справиться со всем этим.

func configureCollectionView(isNib:Bool = false)
{
    if isNib
    {
        //collectionView.register(UINib(nibName: "GalleryCell", bundle:nil), forCellWithReuseIdentifier: identifier)
    }
    else
    {
        //collectionView.register(PhotoCell.self,forCellWithReuseIdentifier:identifier);
    }

}
person Vijayvir Sing Pantlia    schedule 16.12.2016

Если это бета-версия 4 или 5, и я думаю, что она основана на том, что IBOutlets является необязательным, есть ли у вас переопределение initWithCoder в классе? Даже тот, который ничего не делает, кроме как называет супер? Отсутствие может быть вашей проблемой.

Изменить: вы пытались убедиться, что все reuseIdentifiers совпадают в раскадровках и коде?

person Mark Anderson    schedule 06.08.2014
comment
Это Бета5. В Beta5 IBOutlets инициализируются (автоматически при перетаскивании Ctrl) как IBOutlet weak var variableName: VarType. Да, я переопределил initWithCoder. Это ошибка времени компиляции в Beta5 - вы не можете создать свое приложение, если подкласс UIView не переопределяет его. - person OgreSwamp; 06.08.2014
comment
Вот так. Это уже не просто сбой, это настоящая ошибка. - person Mark Anderson; 06.08.2014