Reputation: 97
This is my first time trying to apply a gradient layer to a CustomImageView, and to do that within a UICollectionViewCell, I decided to create the following function:
func configureGradientOverlay() {
let maskedView = UIView(frame: CGRect(x: 0, y: 0.5, width: 400, height: 400))
maskedView.backgroundColor = .black
let gradientMaskLayer = CAGradientLayer()
gradientMaskLayer.frame = maskedView.bounds
gradientMaskLayer.colors = [UIColor.clear.cgColor, UIColor.clear.cgColor, UIColor.clear.cgColor, UIColor.white.cgColor]
gradientMaskLayer.locations = [0, 0.4, 0.6, 0.99]
maskedView.layer.mask = gradientMaskLayer
postImageView.addSubview(maskedView)
}
This seems to do the trick in applying the gradient overlay over the 'postImageView' but as you can see, I've decided to arbitrarily set the width and height of the 'maskedView' to 400. Ideally, I'd like to set the width and height to those of the 'postImageView' but when I try to do that using the code below, the gradient overlay no longer shows up.
let postImageViewSize: CGRect = postImageView.bounds
let postImageViewWidth = postImageViewSize.width
let postImageViewHeight = postImageViewSize.height
let maskedView = UIView(frame: CGRect(x: 0, y: 0.5, width: postImageViewWidth, height: postImageViewHeight))
Can anyone tell me what I might be doing wrong here?
Upvotes: 0
Views: 125
Reputation: 13300
Flanker is actually right. So go ahead and set the width and height to those of the 'postImageView'.
func configureGradientOverlay() {
let postImageViewSize: CGRect = postImageView.bounds
let postImageViewWidth = postImageViewSize.width
let postImageViewHeight = postImageViewSize.height
let maskedView = UIView(frame: CGRect(x: 0, y: 0.5, width: postImageViewWidth, height: postImageViewHeight))
maskedView.backgroundColor = .black
maskedView.layer.mask = gradientMaskLayer
postImageView.addSubview(maskedView)
}
And then call as well the configureGradientOverlay
in layoutSublayers
.
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
let gradientMaskLayer = CAGradientLayer()
gradientMaskLayer.frame = maskedView.bounds
gradientMaskLayer.colors = [UIColor.clear.cgColor, UIColor.clear.cgColor, UIColor.clear.cgColor, UIColor.white.cgColor]
gradientMaskLayer.locations = [0, 0.4, 0.6, 0.99]
maskedView.layer.mask = gradientMaskLayer
}
Voila!
EDIT (aside from the codes), the postImageViewHeight
will be ZERO here, unless you calculate the height in didLayoutSubviews()
or something.
Upvotes: 0
Reputation: 4210
Using a view's bounds
within an initialiser is always pot luck as there's no guarantee that the view will be fully drawn when the bounds property is accessed. A better approach is to override the layer's layoutSublayers(of:)
method.
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
gradientMaskLayer.frame = self.bounds
}
Assuming your layer is created within a view, the view automatically assigns itself as the layer's delegate, thu sproviding the layoutSublayers(of:)
method that you can then override as above. If you are not creaing it within a view then you will have to set up the delegate functionality yourself. I'd recommend doing in within a view :-)
Upvotes: 1