是否将模糊视图添加到标签?

j7dteeu8  于 2022-10-31  发布在  Swift
关注(0)|答案(5)|浏览(224)

如何给标签添加模糊视图?标签位于UIImage前面,我希望标签的背景变得模糊,以便用户更好地阅读文本。我在标签边界内获得了模糊效果,但文本本身消失了(也许也会变得模糊,我不知道为什么)。我也试着用编程的方式添加一个标签,但是我没有让它工作。我感谢任何形式的帮助!

let blur = UIBlurEffect(style: .Light)
    let blurView = UIVisualEffectView(effect: blur)

    blurView.frame = findATeamLabel.bounds
    findATeamLabel.addSubview(blurView)
nue99wik

nue99wik1#

您可以创建自己的BlurredLabel,它可以模糊/取消模糊标签文本。通过CoreImage模糊滤镜,您可以获取标签文本,将其模糊为图像,然后在标签顶部显示该图像。

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:请确保根据您的要求改进此组件(例如,如果已经模糊,请避免模糊,或者如果文本已更改,您可以删除当前模糊并再次应用模糊)。
PSPS:还要考虑到对某些内容应用模糊会使其内容溢出,因此将clipsToBounds = false设置为BlurredLabel或找到其他方法来实现您的视觉效果,以避免模糊图像看起来与之前未模糊的标签文本不在同一位置。
要使用它,您只需创建一个BlurredLabel

let blurredLabel = BlurredLabel()
blurredLabel.text = "56.00 €"

在一些按钮点击,也许你可以实现模糊的blurredLabel.blur()和非模糊的blurredLabel.unblur()

这是blur()通过2.5的blurRadius获得的输出

drnojrws

drnojrws2#

您可以尝试将其发送到标签的视图层次结构的后面。
findATeamLabel.sendSubviewToBack(blurView)

jchrr9hc

jchrr9hc3#

我只是在标签后面添加了一个视图(标签不在视图里面,只是在它前面),然后我在视图中添加了模糊效果...我仍然认为应该有一个更简单的方法。

kb5ga3dv

kb5ga3dv4#

Swift 5 -作为UIView扩展的模糊

extension UIView {

    struct BlurableKey {
        static var blurable = "blurable"
    }

    func blur(radius: CGFloat) {
        guard superview != nil else { return }

        UIGraphicsBeginImageContextWithOptions(CGSize(width: frame.width, height: frame.height), false, 1)
        layer.render(in: UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        guard
            let blur = CIFilter(name: "CIGaussianBlur"),
            let image = image
        else {
            return
        }

        blur.setValue(CIImage(image: image), forKey: kCIInputImageKey)
        blur.setValue(radius, forKey: kCIInputRadiusKey)

        let ciContext  = CIContext(options: nil)
        let boundingRect = CGRect(
            x:0,
            y: 0,
            width: frame.width,
            height: frame.height
        )

        guard
            let result = blur.value(forKey: kCIOutputImageKey) as? CIImage,
            let cgImage = ciContext.createCGImage(result, from: boundingRect)
        else {
            return
        }

        let blurOverlay = UIImageView()
        blurOverlay.frame = boundingRect
        blurOverlay.image = UIImage(cgImage: cgImage)
        blurOverlay.contentMode = .left

        addSubview(blurOverlay)

        objc_setAssociatedObject(
            self,
            &BlurableKey.blurable,
            blurOverlay,
            objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN
        )
    }

    func unBlur() {
        guard
            let blurOverlay = objc_getAssociatedObject(self, &BlurableKey.blurable) as? UIImageView
        else {
            return
        }

        blurOverlay.removeFromSuperview()

        objc_setAssociatedObject(
            self,
            &BlurableKey.blurable,
            nil,
            objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN
        )
    }

    var isBlurred: Bool {
        return objc_getAssociatedObject(self, &BlurableKey.blurable) is UIImageView
    }
}
oalqel3c

oalqel3c5#

没有一个答案对我有效,接受的答案不工作的背景颜色不同的白色,或标签颜色不同的黑色的基础上的意见,它转到另一个问题,但答案使模糊向右移动了很多。因此,经过一些阅读调整CGRect的结果图像。

class BlurredLabel: UILabel {

    var isBlurring = false {
        didSet {
            setNeedsDisplay()
        }
    }

    var blurRadius: Double = 8 {
        didSet {
            blurFilter?.setValue(blurRadius, forKey: kCIInputRadiusKey)
        }
    }

    lazy var blurFilter: CIFilter? = {
        let blurFilter = CIFilter(name: "CIGaussianBlur")
        blurFilter?.setDefaults()
        blurFilter?.setValue(blurRadius, forKey: kCIInputRadiusKey)
        return blurFilter
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        layer.isOpaque = false
        layer.needsDisplayOnBoundsChange = true
        layer.contentsScale = UIScreen.main.scale
        layer.contentsGravity = .center
        isOpaque = false
        isUserInteractionEnabled = false
        contentMode = .redraw
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }

    override func display(_ layer: CALayer) {
        let bounds = layer.bounds
        guard !bounds.isEmpty && bounds.size.width < CGFloat(UINT16_MAX) else {
            layer.contents = nil
            return
        }
        UIGraphicsBeginImageContextWithOptions(layer.bounds.size, layer.isOpaque, layer.contentsScale)
        if let ctx = UIGraphicsGetCurrentContext() {
            self.layer.draw(in: ctx)

            var image = UIGraphicsGetImageFromCurrentImageContext()?.cgImage
            if isBlurring {
                blurFilter?.setValue(CIImage(cgImage: image!), forKey: kCIInputImageKey)
                let ciContext = CIContext(cgContext: ctx, options: nil)
                if let blurOutputImage = blurFilter?.outputImage {
                    let boundingRect = CGRect(
                                x:0,
                                y: blurOutputImage.extent.minY,
                                width: blurOutputImage.extent.width,
                                height: blurOutputImage.extent.height
                            )

                    image = ciContext.createCGImage(blurOutputImage, from: boundingRect)
                }

            }
            layer.contents = image

        }
        UIGraphicsEndImageContext()
    }
}

相关问题