Search code examples
iosswiftuicollectionviewsubview

Subview Disappeas from Collection View Cell with scrolling


I have a UIImageView from storyboard with an outlet in my UICollectionViewController:

@IBOutlet var playButtonView: UIImageView!

Storyboard doesn't allow me to make the outlet anywhere except my View Controller as I have made the view outside the VCs canvas so I can position it dynamically:

Storyboard Screenshot

As a result, I am trying to set the view as cell's subview like so:

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "metadataCell", for: indexPath) as? MetaDataCustomCell
            else { fatalError("Unexpected cell in collection view") }

        if !cell.subviews.contains(playButtonView) {
            let playButtonX = cell.thumbnailImageView.frame.width/2 - playButtonWidthAndHeight/2
            let playButtonY = cell.thumbnailImageView.frame.height/2 - playButtonWidthAndHeight/2
            playButtonView.frame = CGRect(x: playButtonX, y: playButtonY, width: playButtonWidthAndHeight, height: playButtonWidthAndHeight)
            cell.addSubview(playButtonView)

        } else {
            cell.sendSubviewToBack(playButtonView)
        }


        cell.representedAssetIdentifier = asset.localIdentifier

        DispatchQueue.global(qos: .userInitiated).async {

            let requestOption = PHImageRequestOptions()
            requestOption.isSynchronous = true
            self.imageManager.requestImage(for: asset, targetSize:   self.photoSize, contentMode: .aspectFit, options: requestOption, resultHandler: { image, _ in

                if cell.representedAssetIdentifier == asset.localIdentifier {
                    DispatchQueue.main.async {
                        cell.thumbnailImageView.image = image

                    }

                    self.getInfoForAsset(asset: asset) {(assetURL,urlAsset) in

                        if let url = assetURL {

                            if asset.mediaType == .image {
                                self.getDataFromImageURL(imageURL: url, imageAsset: asset, handler: { (metadataDict) in

                                    DispatchQueue.main.async {
                                        cell.dateLabel.text = metadataDict["date"]
                                    }
                                })

                            } else if asset.mediaType == .video {


                                DispatchQueue.main.async {

                                    self.playButtonView.isHidden = false
                                    cell.bringSubviewToFront(self.playButtonView)



                                }
                            }


                        }

                    }


                }
            })
        }


        return  cell

Now, the problem is that the playButtonView only appears when the the first cell is loaded, after I scroll forward or backward to the same cell again, it disappears. Any ideas?


Solution

  • Your playButtonView is a property of your view controller instead of your MetaDataCustomCell. This won't work unless you only have a single MetaDataCustomCell because you only have a single playButtonView that you will always be removing from one cell and adding to the next. Move that property to your cell instead.