NSView makeBackingLayer with CALayer subclass displays no output

99封情书 提交于 2019-12-13 03:29:50

问题


This is a continuation of my question stop-nsview-drawrect-clearing-before-drawing-lockfocus-no-longer-working-on-mojave. I used the pattern lockFocus-graphics context-flushWindow pattern to draw into another view. That no longer works on macOS 10.14, as the backing store of views has changed (for new binaries).

NSView has a method makeBackingLayer that is not there for nothing, I guess. The code snippet below has makeBackingLayer called, and I can have it use my CALayer subclass "TransparentLayer", successfully. Successfully in so far that my subclass's drawInContext: is indeed called, as it should, after setNeedsDisplay is called on the layer. But any drawing I do there does not appear. What am I doing wrong? (ScreenRect is a fullscreen rect.)

My NSView (fullscreen):

- (id)initWithFrame:(NSRect)frame
{
    ALog(@"");

    self = [super initWithFrame:frame];
    if (self) {
        self.wantsLayer = YES;
    }
    return self;
}

- (BOOL) isOpaque { return NO; }
- (BOOL) wantsLayer { return YES; }  // YES for layers, else drawRect
- (BOOL) wantsUpdateLayer { return YES; }

- (CALayer *)makeBackingLayer
// NB: If self.layer is already set, makeBackingLayer is NOT called
{
    ALog(@"");

    // OWN LAYER TYPE (simply subclass of CALayer)
    TransparentLayer *newLayer = [[TransparentLayer alloc] initWithFrame:ScreenRect];
    return newLayer;
}

- (void)updateLayer { ALog(@"(we do not want this)"); }  // (not called)

- (void)drawInContext:(CGContextRef)ctx { ALog( @"ctx=%p",ctx ); } // (not called)

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx { ALog( @"layer=%p ctx=%p",layer,ctx ); } // (not called)

- (void)drawRect:(NSRect)dirtyRect { ALog(@""); } // (not called)

TransparentLayer (fullscreen, too):

- (id)initWithFrame:(NSRect)frame
{
    ALog(@"");

    self = [super init];
    if (self) {        
        self.bounds = frame;    // ?
        self.frame = frame;     // ?
        self.contentsRect = frame;

        self.backgroundColor = [NSColor clearColor].CGColor;  // transparent
        self.opaque = NO;            
    }
    return self;
}

- (void)updateLayer
{
    ALog(@"");
}

- (void)_OUT_display
// THIS (display) IS CALLED when this method is present, else drawInContext:
{
    ALog(@"");
}


- (void)drawInContext:(CGContextRef)ctx
// THIS IS CALLED, BUT NO OUTPUT VISIBLE ON SCREEN
// ViewController calls every cycle: [self.stillView.layer setNeedsDisplay];
{
    ALog(@"");

    // Draw a BLUE square 50x50, screen bottom, left
    CGRect R = CGRectMake(0., 0., 50., 50.  );
    CGContextSetRGBFillColor(ctx, 0,0,1, 1);  // BLUE
    CGContextFillRect(ctx, R);
}

来源:https://stackoverflow.com/questions/54422483/nsview-makebackinglayer-with-calayer-subclass-displays-no-output

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!