Это продолжение моего вопроса stop-nsview-drawrect-clearing-before-drawing-lockfocus-no-long-working-on-mojave .Я использовал паттерн lockFocus-graphics context-flushWindow для рисования в другом виде.Это больше не работает в macOS 10.14, так как изменилось хранилище представлений (для новых двоичных файлов).
NSView имеет метод makeBackingLayer, который, я думаю, не существует ни для чего.В приведенном ниже фрагменте кода вызывается makeBackingLayer, и я могу успешно использовать мой подкласс CALayer «TransparentLayer».Успешно настолько, что drawInContext: моего подкласса действительно вызывается, как и должно быть, после вызова setNeedsDisplay на уровне.Но никакого рисунка, который я там делаю, не появляется.Что я делаю неправильно?(ScreenRect - это полноэкранный прямоугольник.)
Мой NSView (полноэкранный):
- (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 (также полноэкранный):
- (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);
}