0

Is there an elegant way to reference UIImageView (or an UILabel) nested within UICollectionView? (say, using . notation)

That is, without subclassing UICollectionViewCell bolierplate, only for creating an @IBOutlet. For example, at SO thread here.

Would be good to see examples.

C. Derx
  • 187
  • 11
  • If you know the `indexPath`, then you can get the cell using `cellForRowAt` method right? Once you have cell, you should be able to access cell.imageView ? – Rakesha Shastri Aug 07 '18 at 19:19
  • Tried this. `imageView` in `cell.imageView` doesn't work by default. err: `Value of type 'UICollectionViewCell' has no member 'imageView'` – C. Derx Aug 07 '18 at 19:24

3 Answers3

0

There is no elegant way to do this without subclassing UICollectionViewCell.

You could do it without subclassing - by adding the UIImageView programatically, then finding it (somehow) whenever you need it - but that's very much an iOS anti-pattern. (But that still wouldn't allow you to use dot-notation, because the child view isn't a property of UICollectionViewCell)

Matthew
  • 958
  • 9
  • 19
  • Also: as well as being an anti-pattern, you'll probably end up writing _more_ code, and it'll be less typesafe. Finally, you may have problems with cell reuse (because you'll need to explicitly find and remove those `UIImageViews` from the cells before they're reused). – Matthew Aug 07 '18 at 20:39
0

You can not directly use dot notation. But you can assign some tag to the image UIImageView in storyboard. Like 123 here. and access it using that tag.

if let imageView = cell.viewWithTag(123) as? UIImageView {
   //  imageView.image = some image 
}

I am not sure if this is a good pattern. But still you can get rid of the UICollectionViewCell boilerplate.

Sumesh Sivan
  • 173
  • 7
0

Actually, there is a way to achieve that (I would not say that it is "elegant" and I would note that you should not do it most of the time) which is using the tag property of the view:

An integer that you can use to identify view objects in your application.


Consider that you have the following cell:

enter image description here

What you could do is to select the image view/ label and from the interface build, go to the attribute inspector and set its tag:

enter image description here

Therefore, without the need of creating a UICollectionViewCell custom class what you should do in the cellForItemAt is to cast the views based on their tag values:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)

    let imageView = cell.viewWithTag(101) as! UIImageView
    let label = cell.viewWithTag(102) as! UILabel

    // ...
}

Obviously, at this point keep in mind that the given tag value for viewWithTag must match the value set from the interface builder, as well as the sub casting, otherwise it will crash.

Ahmad F
  • 26,570
  • 13
  • 76
  • 124