How can I add a blur view to a label? The label is in front of a UIImage and I wanted the background of the label to be blurred, so that the user can read the text better. I get the Blur effect inside the bounds of the label, but the text itself disappears (maybe also gets blurred, idk why). I also tried to add a label programmatically, but I didn't get it working. I'm thankful for any kind of help!
let blur = UIBlurEffect(style: .Light)
let blurView = UIVisualEffectView(effect: blur)
blurView.frame = findATeamLabel.bounds
findATeamLabel.addSubview(blurView)
You can make your own BlurredLabel
which can blur/unblur its text. Through a CoreImage blur filter you take the text of the label, blur it in an image, and display that image on top of the label.
class BlurredLabel: UILabel {
func blur(_ blurRadius: Double = 2.5) {
let blurredImage = getBlurryImage(blurRadius)
let blurredImageView = UIImageView(image: blurredImage)
blurredImageView.translatesAutoresizingMaskIntoConstraints = false
blurredImageView.tag = 100
blurredImageView.contentMode = .center
blurredImageView.backgroundColor = .white
addSubview(blurredImageView)
NSLayoutConstraint.activate([
blurredImageView.centerXAnchor.constraint(equalTo: centerXAnchor),
blurredImageView.centerYAnchor.constraint(equalTo: centerYAnchor)
])
}
func unblur() {
subviews.forEach { subview in
if subview.tag == 100 {
subview.removeFromSuperview()
}
}
}
private func getBlurryImage(_ blurRadius: Double = 2.5) -> UIImage? {
UIGraphicsBeginImageContext(bounds.size)
layer.render(in: UIGraphicsGetCurrentContext()!)
guard let image = UIGraphicsGetImageFromCurrentImageContext(),
let blurFilter = CIFilter(name: "CIGaussianBlur") else {
UIGraphicsEndImageContext()
return nil
}
UIGraphicsEndImageContext()
blurFilter.setDefaults()
blurFilter.setValue(CIImage(image: image), forKey: kCIInputImageKey)
blurFilter.setValue(blurRadius, forKey: kCIInputRadiusKey)
var convertedImage: UIImage?
let context = CIContext(options: nil)
if let blurOutputImage = blurFilter.outputImage,
let cgImage = context.createCGImage(blurOutputImage, from: blurOutputImage.extent) {
convertedImage = UIImage(cgImage: cgImage)
}
return convertedImage
}
}
PS: Please make sure to improve this component as of your requirements (for example avoid blurring if already blurred or you could remove the current blurred and apply the blurred again if text has changed).
PSPS: Take into consideration also that applying blur to something makes its content bleeds out, so either set clipsToBounds = false
to the BlurredLabel
or find out other way to accomplish your visual effect in order to avoid the blurred image looks like is not in same position as the label unblurred text that was previously.
To use it you can simply create a BlurredLabel
:
let blurredLabel = BlurredLabel()
blurredLabel.text = "56.00 €"
And on some button tap maybe you could achieve blurring as of blurredLabel.blur()
and unblurring as of blurredLabel.unblur()
.
This is the output achieved with blur()
through a blurRadius
of 2.5:
To read more about Gaussian Blur, there is a good article on Wikipedia: https://en.wikipedia.org/wiki/Gaussian_blur
You could try sending it to the back of the view hierarchy for the label. Try
findATeamLabel.sendSubviewToBack(blurView)
I got it working by adding just a View behind the label (the label is NOT inside that view, just in front of it). Then I added the blur effect to the view... I still think there should be an easier way.
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