===编辑以添加有关我想要获得的效果的更多信息===
在一个旧的屏幕保护程序中,我正在绘制类似彗星的东西:一个明亮的物体,它留下了消失的轨迹。因此,在每一帧中,我首先使用透明黑色(alpha设置为.02或类似值)绘制整个屏幕,然后在新位置绘制对象。 (当然,实际上有许多“彗星”,大约50个。)
6或8年前,这在Mac上运行良好,但现在在Mojave中,尽管正在发生淡入淡出,但它会忽然闪烁,就像在每次drawRect调用之前将视图擦除为黑色一样。
我只是在更新我在2010年左右编写的旧屏幕保护程序,我非常喜欢它,并且它停止在Mojave中工作。当时,这种淡入淡出技术效果很好,但是显然已经发生了变化。我怀疑有关后备存储或分层的信息。我希望能对此有所了解,可以找到相关信息的指针,并提供有关最佳做法的建议,以达到类似目的。
(据记录,我是90年代活跃的Mac程序员-有人还记得开发杂志吗?但是现在很少编程,所以Cocoa和Objective C对我来说仍然是“新手”。)>
该代码很简单。在我的视图的drawRect中,在绘制任何打算淡出的新内容之前,我只是做:
// Erase to black, but with much transparency, to fade out any previous drawing
[[NSColor colorWithDeviceRed: 0.0 green: 0.0 blue: 0.0 alpha: 0.02] set];
[NSBezierPath fillRect: [self bounds]];
再次,我确信从挖掘中可以发现这与视图和图层支持有关,但是我不确定修复此问题的最佳实践,我想了解自己在做什么。任何朝着正确方向的指针都值得赞赏。
更新:我发现this的问题和答案看起来很有希望。但是,创建我自己的屏幕外图像真的有必要吗?我希望我可以在某个地方设置布尔值...:-)
答案 0 :(得分:0)
基于答案here,我重新编写了代码以绘制成NSBitmapImageRep,现在看来它工作正常。我的小型测试应用程序中的相关代码:
// In this test app, frame redraws are triggered by a timer
- (void)DrawNewFrame:(NSTimer *)timer
{
// just call our offscreen drawing routine, which will draw and then call setNeedsDisplay
[self drawOffscreen];
}
- (void)drawOffscreen {
// Set up the NSBitmapImageRep if it isn't already
NSBitmapImageRep *cmap = cachedDrawingRep;
if (!cmap) {
cmap = [self bitmapImageRepForCachingDisplayInRect:self.bounds];
cachedDrawingRep = cmap;
}
// Get ready to draw
NSGraphicsContext *ctx = [NSGraphicsContext graphicsContextWithBitmapImageRep:cmap];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:ctx];
// Erase to black, but with much transparency, to fade out any previous drawing
[[NSColor colorWithDeviceRed: 0.0 green: 0.0 blue: 0.0 alpha: 0.02] set];
[NSBezierPath fillRect: [self bounds]];
// Draw a little text if a key is tapped, to see it fade
if( drawText )
{
// Make the font dictionary
NSDictionary *fontDict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSFont fontWithName:@"Helvetica" size:12], NSFontAttributeName,
[NSColor redColor], NSForegroundColorAttributeName,
nil];
NSString *helpStr = @"Fade This String!";
[helpStr drawAtPoint:NSMakePoint(random() % 200, random() % 200) withAttributes: fontDict];
drawText = NO;
}
[NSGraphicsContext restoreGraphicsState];
// Make sure drawRect will get called
[self setNeedsDisplay:YES];
}
- (void)drawRect:(NSRect)rect {
if (cachedDrawingRep) {
[cachedDrawingRep drawInRect:self.bounds];
}
}
它现在完全按预期工作,所以我很高兴。谢谢!