I added a blur effect behind a label. The blur refuses to go behind the label. I tried all 3 of these separately:
label.insertSubview(backgroundBlur, at: 0)
label.addSubview(backgroundBlur)
label.sendSubview(toBack: backgroundBlur)
The thing is I need the width and height of the UIVisualEffectView blur to be based on the the size of the label's text. The text is dynamic. Both labels need to have their own individual backgroundBlur.
How can I get the UIVisualEffectView blur to go behind each indivdual label when it's also based on the label's text's width and height? There should be two labels with 2 backgroundBlurs behind them.
let backgroundBlur: UIVisualEffectView = {
let blur = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.dark))
blur.layer.cornerRadius = 6
blur.layer.masksToBounds = true
return blur
}()
let labelOne: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.boldSystemFont(ofSize: 17)
label.textColor = UIColor.white
label.textAlignment = .center
label.sizeToFit()
label.numberOfLines = 0
return label
}()
let labelTwo: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.boldSystemFont(ofSize: 17)
label.textColor = UIColor.white
label.textAlignment = .center
label.sizeToFit()
label.numberOfLines = 0
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(labelOne)
view.addSubview(labelTwo)
labelOne.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
labelOne.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
labelTwo.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
labelTwo.topAnchor.constraint(equalTo: labelOne.bottomAnchor, constant: 16).isActive = true
putBlurEffectBehindLabel(backgroundBlur, labelOne)
putBlurEffectBehindLabel(backgroundBlur, labelTwo)
}
func putBlurEffectBehindLabel(_ blur: UIVisualEffectView, _ label: UILabel){
blur.frame = label.bounds
// tried these individually but nada
label.insertSubview(backgroundBlur, at: 0)
label.addSubview(backgroundBlur)
label.sendSubview(toBack: backgroundBlur)
blur.center = CGPoint(x: label.bounds.midX, y: label.bounds.midY)
}
I had to add two UIVisualEffectView
named:
backgroundBlurOne
backgroundBlurTwo
Based on @AbdelahadDarwish suggestion of adding the label to the blur instead of adding the blur to the label I was able to get the blur behind the label:
// this is added inside the putBlurEffectBehindLabel function
blur.contentView.addSubview(label)
Also inside the putBlurEffectBehindLabel
function I got the size of the label's text using (text! as NSString).size(withAttributes: [NSAttributedStringKey.font: UIFont])
and then based the width and height of the UIVisualEffectView (the blur) off of that.
I then added the text I wanted for labelOne and backgroundBlurOne in viewDidLoad.
Then I added the text I wanted for labelTwo and the backgroundBlurTwo for it in viewDidAppear. I had to do that so I can use the height from backgroundBlurOne + a 16 point distance so labelTwo could be where I needed it to be from labelOne.
let backgroundBlurOne: UIVisualEffectView = {
let blur = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.dark))
blur.translatesAutoresizingMaskIntoConstraints = false
blur.layer.cornerRadius = 6
blur.layer.masksToBounds = true
blur.isUserInteractionEnabled = false
blur.backgroundColor = UIColor.black.withAlphaComponent(10)
return blur
}()
let backgroundBlurTwo: UIVisualEffectView = {
let blur = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.dark))
blur.translatesAutoresizingMaskIntoConstraints = false
blur.layer.cornerRadius = 6
blur.layer.masksToBounds = true
blur.isUserInteractionEnabled = false
blur.backgroundColor = UIColor.black.withAlphaComponent(10)
return blur
}()
let labelOne: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.systemFont(ofSize: 17)
label.textColor = UIColor.white
label.textAlignment = .center
label.sizeToFit()
label.numberOfLines = 0
return label
}()
let labelTwo: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.systemFont(ofSize: 17)
label.textColor = UIColor.white
label.textAlignment = .center
label.sizeToFit()
label.numberOfLines = 0
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
labelOne.text = "Hello"
putBlurEffectBehindLabel(backgroundBlurOne, labelOne, yDistance: 0)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
labelTwo.text = "Heloooooooooooooooooooooooo"
putBlurEffectBehindLabel(backgroundBlurTwo, labelTwo, yDistance: backgroundBlurOne.frame.height + 16)
}
func putBlurEffectBehindLabel(_ blur: UIVisualEffectView, _ label: UILabel, yDistance: CGFloat){
view.addSubview(blur)
blur.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
blur.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: yDistance).isActive = true
blur.contentView.addSubview(label)
label.centerXAnchor.constraint(equalTo: blur.centerXAnchor).isActive = true
label.centerYAnchor.constraint(equalTo: blur.centerYAnchor).isActive = true
let text = label.text
let textSize = (text! as NSString).size(withAttributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 17)])
blur.widthAnchor.constraint(equalToConstant: textSize.width + 15).isActive = true
blur.heightAnchor.constraint(equalToConstant: textSize.height + 10).isActive = true
}