如何根据标签文本的宽度和高度在 UILabel 后面发送 UIVisualEffectView

How to send UIVisualEffectView behind UILabel when based on the label's text's width and height

我在标签后面添加了模糊效果。模糊拒绝隐藏在标签后面。我分别尝试了所有 3 个:

label.insertSubview(backgroundBlur, at: 0)
label.addSubview(backgroundBlur)
label.sendSubview(toBack: backgroundBlur)

问题是我需要 UIVisualEffectView 模糊的宽度和高度基于标签文本的大小。文字是动态的。两个标签都需要有自己的背景模糊。

当 UIVisualEffectView 也基于标签文本的宽度和高度时,如何让它模糊到每个单独的标签后面?应该有两个标签,后面有 2 个背景模糊。

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)
}

您必须将 UILabel 添加到 UIVisualEffectView

 backgroundBlur.addSubview(labelOne)
 backgroundBlur.addSubview(labelTwo)
  1. 添加背景模糊并设置约束

  2. 然后将 labelOne、labelTwo 添加到 backgroundBlur 并具有约束条件

    或者全部添加到UIView,然后用constraint

    连接起来

    别忘了translatesAutoresizingMaskIntoConstraints = false

声明:

let backgroundBlur: UIVisualEffectView = {
        let blur = UIVisualEffectView(effect: UIBlurEffect(style: 
        UIBlurEffectStyle.dark))
        blur.layer.cornerRadius = 6
        blur.layer.masksToBounds = true
        blur.translatesAutoresizingMaskIntoConstraints = false
        return blur
    }()

    let labelOne: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    let labelTwo: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

ViewDidLoad

self.view.addSubview(backgroundBlur)
self.view.addSubview(labelOne)
self.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

labelOne.text = "asdhaskdas saldhlsahdsa laskdhsakhd asdlhkhsad"
labelTwo.text = "asdhaskdas saldhlsahdsa laskdhsakhd asdlhkhsad"


labelOne.numberOfLines = 0
labelTwo.numberOfLines = 0

backgroundBlur.topAnchor.constraint(equalTo: labelOne.topAnchor, constant: -8).isActive = true
backgroundBlur.bottomAnchor.constraint(equalTo: labelTwo.bottomAnchor, constant: 8).isActive = true
backgroundBlur.trailingAnchor.constraint(equalTo: labelOne.trailingAnchor, constant: 8).isActive = true
backgroundBlur.leadingAnchor.constraint(equalTo: labelOne.leadingAnchor, constant: -8).isActive = true

我不得不添加两个 UIVisualEffectView 命名为:

backgroundBlurOne
backgroundBlurTwo

根据@AbdelahadDarwish 将标签添加到模糊而不是将模糊添加到标签的建议,我能够在标签后面得到模糊:

// this is added inside the putBlurEffectBehindLabel function
blur.contentView.addSubview(label)

同样在 putBlurEffectBehindLabel 函数中,我使用 (text! as NSString).size(withAttributes: [NSAttributedStringKey.font: UIFont]) 获得了标签文本的大小 然后基于 UIVisualEffectView(模糊)的宽度和高度。

然后我在 viewDidLoad 中为 labelOne 和 backgroundBlurOne 添加了我想要的文本。

然后我在 viewDidAppear 中为 labelTwo 添加了我想要的文本和 backgroundBlurTwo。我必须这样做,这样我才能使用来自 backgroundBlurOne 的高度 + 16 点距离,这样 labelTwo 就可以成为我需要来自 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
}