Search code examples
swiftuiimageviewfocusuicollectionviewcelltvos

tvOS parallax effect for subviews of UIImageView inside cell


I have a tvOS app with a UICollectionView. Inside each cell there's a UIImageView that has the adjustsImageWhenAncestorFocused set to true, which gives me the nice parallax effect when the cell is focused.

I am trying to add a banner on top of that image and have it "stick" to it, so that the parallax is also applied on it.

I've tried adding it as a subview, adding it as a sublayer, messing with the constraints, but nothing worked. Whenever the cell is focused, the image has the effect and the banner stays still.


Solution

  • Right now there's no way to add it to the UIImageView while also getting Apple's parallax effect.

    So you have to either implement the effect programatically, or use CGContext to draw the image and a banner on top of it.

    I'm doing the latter to have rounded images in a collectionViewCell while also keeping Apple's own parallax effect. This kinda looks like this:

    imageView.sd_setImage(with: URL(string:url), placeholderImage: UIImage(named: "placeholder"), options: SDWebImageOptions.avoidAutoSetImage) { [weak self] (image, error, cacheType, url) in
        if let image = image {
            if let strongself = self {
                UIGraphicsBeginImageContext(strongself.imageView.frame.size)
                if let ctx = UIGraphicsGetCurrentContext() {
                    let layer = CALayer()
                    layer.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: strongself.imageView.frame.size)
                    layer.cornerRadius = 8
                    layer.masksToBounds = true
                    layer.contentsGravity = "resizeAspectFill"
                    layer.contents = image.cgImage
                    layer.render(in: ctx)
                    let processedImage = UIGraphicsGetImageFromCurrentImageContext()
                    UIGraphicsEndImageContext()
                    strongself.imageView.image = processedImage
                }
            }
        }
    }
    

    Make sure to move stuff to a background thread when needed and that a cell might have been reused by the time an image has loaded. So add a check inside loadImage completion handler for a unique id.