Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS invert mask in drawRect

With the code below, I am successfully masking part of my drawing, but it's the inverse of what I want masked. This masks the inner portion of the drawing, where I would like to mask the outer portion. Is there a simple way to invert this mask?

myPath below is a UIBezierPath.

CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; CGMutablePathRef maskPath = CGPathCreateMutable(); CGPathAddPath(maskPath, nil, myPath.CGPath); [maskLayer setPath:maskPath]; CGPathRelease(maskPath); self.layer.mask = maskLayer; 
like image 966
Mr Ordinary Avatar asked Jan 19 '13 06:01

Mr Ordinary


Video Answer


2 Answers

With even odd filling on the shape layer (maskLayer.fillRule = kCAFillRuleEvenOdd;) you can add a big rectangle that covers the entire frame and then add the shape you are masking out. This will in effect invert the mask.

CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; CGMutablePathRef maskPath = CGPathCreateMutable(); CGPathAddRect(maskPath, NULL, someBigRectangle); // this line is new CGPathAddPath(maskPath, nil, myPath.CGPath); [maskLayer setPath:maskPath]; maskLayer.fillRule = kCAFillRuleEvenOdd;         // this line is new CGPathRelease(maskPath); self.layer.mask = maskLayer; 
like image 134
David Rönnqvist Avatar answered Sep 20 '22 19:09

David Rönnqvist


For Swift 3.0

func mask(viewToMask: UIView, maskRect: CGRect, invert: Bool = false) {     let maskLayer = CAShapeLayer()     let path = CGMutablePath()     if (invert) {         path.addRect(viewToMask.bounds)     }     path.addRect(maskRect)      maskLayer.path = path     if (invert) {         maskLayer.fillRule = kCAFillRuleEvenOdd     }      // Set the mask of the view.     viewToMask.layer.mask = maskLayer; } 
like image 25
arvidurs Avatar answered Sep 19 '22 19:09

arvidurs