I have created a custom view class. I have a image view that I want to blur. I have added the blurring effect in the code below, but obviously it doesn't work because the bounds of the image view is wrong. Due to auto layout haven't calculated the correct sizes for height and width of the image view yet. However which method should I override to access correct position and size attributes?
And what would be the solution for only adding it once?
class ProductListingCell: UICollectionViewCell {
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var sharpImageView: UIImageView!
@IBOutlet weak var blurImageView: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
let blurEffect = UIBlurEffect(style: .Light)
let visualEffectView = UIVisualEffectView(effect: blurEffect)
visualEffectView.frame = blurImageView.bounds
blurImageView.addSubview(visualEffectView)
}
}
(edit) Maybe an answer:
Just after posting the question I found this method. Would this be the correct way to do it?
override func layoutSubviews() {
super.layoutSubviews()
layoutIfNeeded()
let blurEffect = UIBlurEffect(style: .Light)
let visualEffectView = UIVisualEffectView(effect: blurEffect)
visualEffectView.frame = blurImageView.bounds
blurImageView.addSubview(visualEffectView)
}
Yes, your are correct: layoutSubviews()
is the way to go.
However, you don't need and actually shouldn't use layoutIfNeeded()
inside the layoutSubviews()
body. This is because what layoutIfNeeded()
does is that checks if a particular internal flag is set on the view (it's set whenever you or the system call setNeedsLayout()
) and if that's the case it calls layoutSubviews()
on the view (the very same method from where you called it). With other words: You might create a never ending recursion cycle here if you do anything that invalidates the current layout in the layoutSubviews()
method before calling layoutIfNeeded()
.
I tested your code with and without the layoutIfNeeded()
call in a sample project and both implementations yield the same (correct) result. Please check if you made any other changes to your code.
When layoutSubviews()
is called on your custom view you can be sure that the system has set the view's frame after resolving all layout constraints that constrain the view to its sibling views and its superview. However, you need to call super.layoutSubviews()
first in order to properly position all of the view's subviews.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With