4

There are several posts on nil outlets in a UICollectionViewCell class like this and this, but none of the solutions worked. Using a strong outlet instead of a weak one failed, the registerClass solution doesn't apply since the cell doesn't use a custom XIB, the data sources and delegates are wired properly, etc.

In this case, the outlet is a UIImageView which is nil when accessed inside the UICollectionViewCell class, yet works fine when accessed outside.

UICollectionView code:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(AlbumCellIdentifier, forIndexPath: indexPath) as! AlbumCell

    cell.imageView.image = getThumbnail()
    cell.imageView.contentMode = .ScaleAspectFill        
    cell.imageView.layer.masksToBounds = true
    cell.imageView.layer.cornerRadius = cell.frame.size.width / 2

    return cell
}

UICollectionViewCell code:

class AlbumCell: UICollectionViewCell {
    @IBOutlet weak var imageView: UIImageView!

    override init(frame: CGRect) {
        super.init(frame: frame)

        doInit(frame)
    }


    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        doInit(frame)
    }


    private func doInit(frame: CGRect) {
        // Round corners
        imageView.layer.masksToBounds = true
        imageView.layer.cornerRadius = frame.size.width / 2
    }
}

Rounding corners inside the UICollectionViewCell class fails because imageView is nil, yet rounding corners inside of the UICollectionView class succeeds so imageView does appear to be connected.

Why is imageView nil inside of the UICollectionViewCell class?

Community
  • 1
  • 1
Crashalot
  • 31,452
  • 56
  • 235
  • 393

1 Answers1

3

You might want to try calling doInit in awakeFromNib however I think the frame may not have been initialized yet (didn't test that though):

override func awakeFromNib() {
  super.awakeFromNib()
  doInit(frame)
}

Since you want to update cornerRadius with respect to view's frame, I would do that in layoutSubviews instead so any frame change will directly reflect to corner radius value:

override func awakeFromNib() {
  super.awakeFromNib()
  imageView.layer.masksToBounds = true
}

override func layoutSubviews() {
  super.layoutSubviews()
  imageView.layer.cornerRadius = frame.size.width / 2
}

Update: Since you said, you don't use a nib file to load the view, just move imageView.layer.masksToBounds = true into init(frame: CGRect) and delete awakeFromNib.

ozgur
  • 41,172
  • 16
  • 73
  • 106
  • Sorry should have clarified that no nib is used ... would this still help? – Crashalot Apr 03 '16 at 21:07
  • Totally. just move `imageView.layer.masksToBounds = true` into `init(frame: CGRect)` and implement `layoutSubviews` like above. – ozgur Apr 03 '16 at 21:09
  • You don't need to. You can delete it if you don't use nib file. See my update. – ozgur Apr 03 '16 at 21:12