xcode22
xcode22

Reputation: 128

How to make a CAShapeLayer have a blur effect?

I have this CAShapeLayer that I want to have a blur effect. How would I be able to do that?

EDIT I tried it this way but the blur view doesn't show. Anyone know why? Thanks!

func createLayer(in rect: CGRect) -> CAShapeLayer{
        


        let effectView = UIVisualEffectView(effect:UIBlurEffect(style: .regular))
        effectView.frame = rect
        let view = UIView(frame: rect)
        view.addSubview(effectView)


        let mask = CAShapeLayer()
        mask.frame = rect
        mask.cornerRadius = 10
        effectView.layer.mask = mask


        maskLayer.append(mask)
        layer.insertSublayer(mask, at: 1)
    
        return mask
}

Upvotes: 1

Views: 1699

Answers (1)

Duncan C
Duncan C

Reputation: 131416

The short answer: You don't. You can add a visual effects view (UIVisualEffectView) of type blur (a UIBlurEffect) on top of the shape layer's view, or you could write code that takes the contents of the shape layer, applies a Core Image filter to it, and copies the output to another layer.

Using a UIVisualEffectView is a lot easier than working with Core Image filters, but a visual effect view operates on a view, not a layer. You'll need to make the shaper layer be part of the layer's layer hierarchy in order to use it.

Edit:

Your code has errors and doesn't really make sense. Your method createLayer (which I guess is a view controller instance method?) creates and returns a shape layer.

That method creates a throw-away UIView that is never added to the view hierarchy, nor passed back to the caller. That view will get deallocated as soon as your method returns.

Next you create a visual effects view and make that a subview of the throw-away view. Since the only place that view is attached is to the throw-away view, it will also get deallocated as soon as your method returns.

Next you create a shape layer and set it up as the mask of some other layer maskLayer, which you don't explain. Nor do you install a path into the shape layer.

If you have a view called shapeView, of class ShapeView, and you want to attach a visual effects view to it, you could use code like this:

class ViewController: UIViewController {
    
    @IBOutlet weak var shapeView: ShapeView!
    var blurView: UIVisualEffectView?

    override func viewDidLoad() {
        super.viewDidLoad()
        blurView = UIVisualEffectView(effect:UIBlurEffect(style: .regular))
        blurView?.frame = shapeView.frame

        //Add the blur view on top of the shape view
        view.addSubview(blurView!) 
    }

    override func viewDidLayoutSubviews() {
        //Update the blurView's frame if needed
        blurView?.frame = shapeView.frame 
    }
}

Upvotes: 2

Related Questions