Why does UIGraphicsGetCurrentContext return nil after UIGraphicsBeginImageContext

后端 未结 1 1560
抹茶落季
抹茶落季 2021-01-26 06:27

I am following a code example to make a blurred UILabel, https://stackoverflow.com/a/62224908/2226315.

My requirement is to make the label on blur after label initializat

相关标签:
1条回答
  • 2021-01-26 06:49

    Here is a better solution - instead of retrieving the blurred image, just let the label blur itself.

    When you need it to be blurred, set label.isBluring = true. Also, this solution is better for performance, because it reuses the same context and does not need the image view.

    class BlurredLabel: UILabel {
        
        var isBlurring = false {
            didSet {
                setNeedsDisplay()
            }
        }
    
        var blurRadius: Double = 2.5 {
            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) {
            fatalError("init(coder:) has not been implemented")
        }
        
        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, let cgImage = image {
                    blurFilter?.setValue(CIImage(cgImage: cgImage), forKey: kCIInputImageKey)
                    let ciContext = CIContext(cgContext: ctx, options: nil)
                    if let blurOutputImage = blurFilter?.outputImage,
                       let cgImage = ciContext.createCGImage(blurOutputImage, from: blurOutputImage.extent) {
                        image = cgImage
                    }
                }
                layer.contents = image
            }
            UIGraphicsEndImageContext()
        }
    }
    
    0 讨论(0)
提交回复
热议问题