Connected IBOutlets are not initialized

2019-05-06 15:36发布

I've implemented custom UICollectionViewCell class in Swift, created storyboard with UICollectionViewCotroller, assigned my custom controller class, custom cell class, cell id etc... Basically everything required to make UICollectionViewController work.

In storyboard cell prototype I've added few views and connected them as IBOutlets to my custom cell class:

enter image description here

here my IBOutlets in code (as you can see, they are connected): enter image description here

I registered custom cell class in my controller too:

self.collectionView.registerClass(MyCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)

When I dequeue my cell in code it returns cell of my custom type but both IBOutlets aren't initialised (equal 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 I put breakpoint on if statement above and do po cell I have this output:

(lldb) po cell
0x00007fa799f4cdf0
 {
  UIKit.UICollectionViewCell = {
    UIKit.UICollectionReusableView = {
      UIKit.UIView = {
        UIKit.UIResponder = {
          ObjectiveC.NSObject = {}
        }
      }
    }
  }
  selectionView = nil
  imageView = nil
}

Any ideas why IBOutlets aren't initialised?

4条回答
三岁会撩人
2楼-- · 2019-05-06 15:54

I was having the same problem starting in Beta5, though with xib not with storyboard. In the xib case, it appears to be a problem with

init(nibName: nil, bundle: nil) 

not picking up the default xib filename. When I changed to an explicit nibName

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

then it started working again. Could the the same issue with storyboard - if there's a way to force the storyboard name, I'd try that.

查看更多
男人必须洒脱
3楼-- · 2019-05-06 15:55

If this is beta 4 or 5, and I think it is based on the IBOutlets being optional, do you have initWithCoder overridden in the class? Even one that does nothing but call super? That being missing might be your problem.

Edit: Have you tried making sure the reuseIdentifiers all match up in the storyboards and code?

查看更多
叼着烟拽天下
4楼-- · 2019-05-06 15:57

It happens because IBOutlets are connected later, after initWithCoder has finished.

To setup your controls after they've been connected, you can override - applyLayoutAttributes: in your UIColletionViewCell subclass.

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

According to documentation, it's an empty method, meant to be overridden in order to apply custom layout attributes to the view. Sounds about right.

查看更多
小情绪 Triste *
5楼-- · 2019-05-06 15:57

Well , I also faced this problem , and my issues is solved by commenting Register api of collection view as following code snippet . I believed that as we are using storyboard . and there we have given all information like (Class , outlets and identifier ) . so storyboard handle all this .

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

}
查看更多
登录 后发表回答