1

我正在自定义我的drawRect:方法,该方法用于绘制 aNSImage如果它已“加载”(加载需要几秒钟的时间,因为我是从 a 抓取它WebView),如果图像没有,则推迟绘制图像直到稍后尚未加载。

- (void)drawRect:(NSRect)dirtyRect
{
    NSImage *imageToDraw = [self cachedImage];
    if (imageToDraw != nil) {
        [imageToDraw drawInRect:dirtyRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil];
    } else {
        //I need help here
        [self setNeedsDisplay:YES];
    }
}

我的问题是如何做后者。[self cachedImage]如果图像不可用,则返回nil,但在接下来的几秒钟内它可能随时可用,那时我想绘制它,因为自定义视图已经在屏幕上。

我最初的直觉是在图像不可用时尝试调用[self setNeedsDisplay:YES];,希望它会告诉 CocoadrawRect下次再次调用(一次又一次,直到图像被绘制),但这不起作用。

关于我可以从这里去哪里的任何指示?


编辑:

WebView当 loadRequest 已完全处理时,我非常了解该火灾的委托方法。然而,由于应用程序其余部分的结构,使用这些将非常困难,但我想我现在会尝试以某种方式使用它们,因为目前的答案。(另请注意,我的 drawRect: 方法相对较轻,除了我上面已经拥有的代码之外什么都没有。)

我目前有大约 10 多个自定义视图,每个视图都有自定义数据,要求相同的 WebView 为每个视图生成图像。同时,我从 NSCache 中获取图像(使用与每个自定义视图对应的标识符)并在它不存在或需要更新时创建它,如果它还不可用则返回 nil。- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame因此,它不像从或其他方法调用 [view setNeedsDisplay:YES] 那样容易。

4

3 回答 3

4

我最初的直觉是尝试调用 [self setNeedsDisplay:YES]; 如果图像不可用,希望它会告诉 Cocoa 下次再次调用 drawRect (一次又一次,直到图像被绘制)

这将是非常低效的,即使它有效。

在接下来的几秒钟内它可能随时可用,那时我想画它

因此,当发生这种情况时,请致电[view setNeedsDisplay:YES].

如果您无法直接确定图像何时可用,则必须进行轮询。以合理的间隔设置重复NSTimer- 比如说 0.25 秒左右。(这也是相当低效的,但至少它每秒只运行 4 次而不是 60 次或更糟。这是两个因素之间的权衡:您想要使用多少 CPU 和电池电量,以及时间之间的延迟时间图像变为可用以及您显示它的时间。)

我的 drawRect: 方法的重量相对较轻,除了我上面已经有的代码之外什么都没有。

即使你什么都不做-drawRect:,Cocoa 仍然需要在幕后做很多工作——它需要管理脏矩形,清除窗口后备存储的适当区域,将其刷新到屏幕等。那是免费的。

于 2012-05-12T22:59:11.630 回答
1

好吧,当下载完成时,通常会调用一些委托方法。您应该实现该方法并setNeedsDisplay:YES在那里调用。

于 2012-05-12T22:55:29.543 回答
0

webkit 的文档:

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/DisplayWebContent/Tasks/ResourceLoading.html#//apple_ref/doc/uid/20002028-CJBEHAAG

您必须在 webview 委托中实现以下方法:

 - webView:resource:didFinishLoadingFromDataSource: 

在那里你可以打电话[view setNeedsDisplay:Yes]

于 2012-05-12T23:09:10.093 回答