UIVisualEffectView with mask layer

Solution 1:

Ive now found a solution after digging around for a bit. Im assuming you're using Xcode 8 as the layer.mask has a known bug where you cannot have both a blur, and a mask on the same layer.

After messing around with a playground I have fixed the problem, so will try to adapt your code to match my solution. If you use the "mask" property of the blurView instead, then you should have no issues. There has been a bug report made to Apple I believe in regards to the layer.mask not working

This is your current code at the end

let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
maskLayer.fillRule = kCAFillRuleEvenOdd

let borderLayer = CAShapeLayer()
borderLayer.path = circle.cgPath
borderLayer.strokeColor = UIColor.white.cgColor
borderLayer.lineWidth = 10
blur.layer.addSublayer(borderLayer)

blur.layer.mask = maskLayer

Instead of this, try using the following:

let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
maskLayer.fillRule = kCAFillRuleEvenOdd

let borderLayer = CAShapeLayer()
borderLayer.path = circle.cgPath
borderLayer.strokeColor = UIColor.white.cgColor
borderLayer.fillColor = UIColor.clear.cgColor //Remember this line, it caused me some issues
borderLayer.lineWidth = 10

let maskView = UIView(frame: self.view.frame)
maskView.backgroundColor = UIColor.black
maskView.layer.mask = maskLayer

blur.layer.addSublayer(borderLayer)
blur.mask = maskView

Let me know if you have any issues!

Solution 2:

In addition to Jack's solution, if you are on iOS >11 then just set blur.layer.mask to the maskLayer:

if #available(iOS 11.0, *) {
    blur.layer.mask = maskLayer
} else {
    let maskView = UIView(frame: self.view.frame)
    maskView.backgroundColor = UIColor.black
    maskView.layer.mask = borderLayer
    blur.mask = maskView
}