I simply do the following in code:
let path = UIBezierPath(rect: blurView.bounds)
path.usesEvenOddFillRule = true
path.append(UIBezierPath(rect: CGRect(x: 100, y: 100, width: 100, height: 100)))
path.append(UIBezierPath(rect: CGRect(x: 150, y: 150, width: 100, height: 100)))
//here you can add more paths, but the number is not known
let layer = CAShapeLayer()
layer.path = path.cgPath
layer.fillRule = .evenOdd
blurView.layer.mask = layer
and the effect is following:
Two rectangles overlapping one another. But all I need is to combine area from both rectanges, not to exclude everlapping area. Is it possible?
2
Answers
Using the "even-odd" fill rule is great for "cutting a hole" in a path. However, this code:
will be, as you’ve seen, problematic.
Depending on what all you are wanting to do, you could use a library such as ClippingBezier which allows you to manipulate paths with boolean actions.
Or, you can use a custom
CALayer
like this to "invert" multiple paths to use as a "cutout mask":To show it in use, we’ll use this image:
In a standard
UIImageView
, overlaid with a blurUIVisualEffectView
, and then use theBasicCutoutLayer
class with two overlapping rects as the blur view’s layer mask:Before applying the mask, it looks like this:
after applying the mask we get:
As we see, the "overlap" displays as we want.
That was a very simple, basic example. For a more advanced example, take a look at this:
along with a subclassed
UIVisualEffectView
for convenience:and an example controller:
When run, this example will cycle through overlapping rect, overlapping ovals, some varying width lines, and some assorted shapes (just to give an idea):
I would go with ClippingBezier because it is fast, easy to use and neat. It’ll be something like this:
Output:
EDIT
It appears that this method doesn’t work properly when using UIBezierPath(roundedRect:cornerRadius:). To overcome that, here is how we can construct our own func to do that:
We can also extend the above-mentioned solution to multiple paths. Here is one way to create the union of multiple paths:
Here is an example:
And the output: