title: Create a CALayer mask by combining multiple paths
body: <p>I'm trying to create a mask for a CALayer containing an image. This mask shall be able to use the union of multiple paths or the inverse of the union. In terms of a venn diagram that would be a disjunction or a joint denial (look here for graphics of the venn diagram that I can't post: <a href="https://en.wikipedia.org/wiki/Logical_connective#Common_logical_connectives" rel="nofollow noreferrer">https://en.wikipedia.org/wiki/Logical_connective#Common_logical_connectives</a>).
  I also started a thread in a dedicated iOS-forum with lots of graphics and even more example code: <a href="http://www.raywenderlich.com/forums/viewtopic.php?f=2&amp;t=7155" rel="nofollow noreferrer">http://www.raywenderlich.com/forums/viewtopic.php?f=2&amp;t=7155</a></p>
  
  <p>I do succeed to create the first case: a union of multiple paths (disjunction).</p>
  
  <p>You can copy the code into a new single screen app to try it out (don't forget to include the Quartz framework):</p>
  
  <pre><code>- (void)viewDidLoad
  {
      [super viewDidLoad];
      // Do any additional setup after loading the view, typically from a nib.
  
      // create a yellow background
      UIView *bg = [[UIView alloc] initWithFrame:self.view.bounds];
      bg.backgroundColor = [UIColor yellowColor];
      [self.view addSubview:bg];
  
      // create the layer on top of the yellow background that will be masked
      CALayer *imageLayer = [CALayer layer];
      imageLayer.frame = self.view.layer.bounds;
      imageLayer.backgroundColor = [[UIColor blueColor] CGColor];
  
      // create the mask that will be applied to the layer on top of the
      // yellow background
      CAShapeLayer *maskLayer = [CAShapeLayer layer];
      maskLayer.fillRule = kCAFillRuleEvenOdd;
      maskLayer.frame = self.view.frame;
      CAShapeLayer *maskSubLayer1 = [CAShapeLayer layer];
      maskSubLayer1.fillRule = kCAFillRuleEvenOdd;
      maskSubLayer1.frame = self.view.frame;
      CAShapeLayer *maskSubLayer2 = [CAShapeLayer layer];
      maskSubLayer2.fillRule = kCAFillRuleEvenOdd;
      maskSubLayer2.frame = self.view.frame;
  
      // add the paths to sublayers of the mask
      maskSubLayer1.path = CGPathCreateWithRect((CGRect){{100, 140}, {100, 150}}, nil);
      maskSubLayer2.path = CGPathCreateWithEllipseInRect((CGRect){{80, 40}, {190, 190}}, nil);
      // add the sublayers to the mask
      // (instead of using CGPathAddPath())
      [maskLayer addSublayer:maskSubLayer1];
      [maskLayer addSublayer:maskSubLayer2];
      // apply the mask to the layer on top of the yellow background
      imageLayer.mask = maskLayer;
      [self.view.layer addSublayer:imageLayer];
  
  }
  </code></pre>
  
  <p>However, the inverse seems untamable, for instance with a masked mask:</p>
  
  <pre><code>- (void)viewDidLoad
  {
      [super viewDidLoad];
      // Do any additional setup after loading the view, typically from a nib.
  
      // create a yellow background
      UIView *bg = [[UIView alloc] initWithFrame:self.view.bounds];
      bg.backgroundColor = [UIColor yellowColor];
      [self.view addSubview:bg];
  
      // create the layer on top of the yellow background that will be masked
      CALayer *imageLayer = [CALayer layer];
      imageLayer.frame = self.view.layer.bounds;
      imageLayer.backgroundColor = [[UIColor blueColor] CGColor];
  
      // create the mask that will be applied to the layer on top of the
      // yellow background
      CAShapeLayer *maskLayer = [CAShapeLayer layer];
      maskLayer.fillRule = kCAFillRuleEvenOdd;
      maskLayer.frame = self.view.frame;
      CAShapeLayer *maskSubLayer1 = [CAShapeLayer layer];
      maskSubLayer1.fillRule = kCAFillRuleEvenOdd;
      maskSubLayer1.frame = self.view.frame;
      CAShapeLayer *maskSubLayer2 = [CAShapeLayer layer];
      maskSubLayer2.fillRule = kCAFillRuleEvenOdd;
      maskSubLayer2.frame = self.view.frame;
  
      // add the paths to sublayers of the mask
      maskSubLayer1.path = CGPathCreateWithRect((CGRect){{100, 140}, {100, 150}}, nil);
      [maskLayer addSublayer:maskSubLayer1];
      maskSubLayer2.path = CGPathCreateWithEllipseInRect((CGRect){{80, 40}, {190, 190}}, nil);
      [maskLayer addSublayer:maskSubLayer2];
      // use the maskLayer to mask the maskBackgroundLayer
      CALayer *maskBackgroundLayer = [CAShapeLayer layer];
      maskBackgroundLayer.frame = self.view.layer.bounds;
      maskBackgroundLayer.backgroundColor = [[UIColor greenColor] CGColor];
      maskBackgroundLayer.mask = maskLayer;
  
      // apply the maskBackgroundLayer to the layer on top of the yellow background
      imageLayer.mask = maskBackgroundLayer;
      [self.view.layer addSublayer:imageLayer];
      // just for testing: instead of the 2 lines above look at the maskBackgroundLayer
  //    [self.view.layer addSublayer:maskBackgroundLayer];
  
  }
  </code></pre>
  
  <p>I'm looking for ideas how to achieve this effect. </p>
  
  <p>Similar questions are:
  <a href="https://stackoverflow.com/questions/15551384/ios-clipping-union-of-two-paths-using-uibezierpath-appendpath">iOS - Clipping union of two paths using UIBezierPath appendPath</a>
  (not applicable in my case since the intersection can be irregular)
  <a href="https://stackoverflow.com/questions/10723237/combining-intersecting-cgpaths-on-ios?rq=1">Combining Intersecting CGPaths on iOS</a>
  (unresolved)</p>