3

Using NSBezierPath addClip only limits drawing to inside the path used for clipping. I'd like to do the opposite - Only draw outside.

- (void)drawRect:(NSRect)dirtyRect {
    NSBezierPath *dontDrawInThis = ...;

    //We want an opposite mask of [dontDrawInThis setClip];

    //Drawing comes here
}
Avishay Cohen
  • 2,418
  • 1
  • 22
  • 40

2 Answers2

3

This was my solution:

- (void)drawRect:(NSRect)dirtyRect {
    NSBezierPath *dontDrawInThis = ...;

    // The mask is the whole bounds rect, subtracted dontDrawInThis

    NSBezierPath *clip = [NSBezierPath bezierPathWithRect:self.bounds];
    [clip appendBezierPath:dontDrawInThis.bezierPathByReversingPath];
    [clip setClip];

    //Drawing comes here
}

For iOS replace NSRect with CGRect.

Avishay Cohen
  • 2,418
  • 1
  • 22
  • 40
  • `bezierPathByReversingPath` is in Xaramin's iOS section. – Todd Jan 29 '17 at 21:32
  • Thanks a lot! This really helped me. I'm not sure why just using the reversed path didn't work, see my answer for the swift version. Also this answer doesn't include any Xamarin calls, and neither does mine. – nteissler Dec 07 '19 at 16:36
2

Swift version of @avishic's answer

override func draw(_ dirtyRect: NSRect) {
    super.draw(dirtyRect)
    let restrictedPath = NSBezierPath()

    // fill the restricted path with shapes/paths you want transparent...

    let fullRect = NSBezierPath(rect: self.bounds)
    fullRect.append(restrictedPath.reversed)
    fullRect.setClip()
    NSColor.blue.setFill()

    frame.fill()
}
nteissler
  • 1,513
  • 15
  • 16