2

我一直在为 iOS 开发一个类似 cad 的绘图应用程序,它仔细使用脏矩形剪辑来提供流畅的绘图体验 - 几个月来一直运行良好。现在,我知道 iOS 不会自动裁剪脏矩形,但 CoreGraphics 会。作为参考,这是我的主视图的 drawRect 函数的序言(省略了实际的绘图机制)

- (void)drawRect:(CGRect)dirtyRect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);

    if ( !CGRectIsNull(dirtyRect))
    {
        CGContextClipToRect( context, dirtyRect );
    }

    CGContextConcatCTM( context, self.viewTransform );

    .... drawing here, all done by CG* vector and bitmap functionsa

    CGContextRestoreGState( context );
}

现在,这段代码运行得很漂亮,iOS6、iOS7 的早期版本等等。顺利如黄油。但就在最近,我看到了一组非常奇怪的行为,我很好奇这里是否有人有类似的经历。

首先,我以正常方式触发重绘,当我需要重绘整个视图时触发 setNeedsDisplay,并且 setNeedsDisplayInRect 只为需要重绘的一小部分传递脏矩形。奇怪的是,最近当我调用 setNeedsDisplayInRect 时,我传递的矩形被忽略,而是 drawRect 接收到与视图边界匹配的矩形,而不是预期的子矩形。我只是在测试人员报告与以前的版本相比绘图性能非常差时才注意到这一点 - 我最近使用模拟器太多并且没有注意到:/

我怀疑这可能是某种多脏矩形联合的结果,所以我重载了 setNeedsDisplay 和 setNeedsDisplayInRect,跟踪它们何时被调用,但这无济于事。所以我决定在我的渲染视图类中手动跟踪我的脏矩形作为 iVar。这是第二个奇怪的地方:当我剪辑到现在正确的脏矩形时,脏矩形之外的内容被清除了。

他们不应该被清除。我已明确设置 self.clearsContextBeforeDrawing = NO,所以我不明白为什么我看到的行为会发生,尤其是过去没有发生的时候。

现在,我可能会做一个 git-bisect 风格的调试,看看我是否能找到一个没有这个错误的版本。但我希望这里有 CoreGraphics 经验的人能给我一些概念上的支持。这让我完全困惑。

PS自从我花了几个月的时间围绕绘图工具开发应用程序以来,我已经很长时间没有接触过我的应用程序的绘图代码了。这就是为什么我怀疑对 iOS7 的绘图管道的更改可能会在这里发挥某种作用。

4

3 回答 3

0

drawRect:dirtyRect 适用于 mac。对于 ios,您应该使用 drawRect:rect。应该使用 setNeedsDisplay 调用它。

于 2013-11-15T13:00:39.783 回答
0

我认为您需要在 drawRect 方法中的代码中包含这一行:-

 [super drawRect:dirtyRect];
于 2013-11-12T13:00:47.480 回答
0

对于将来在寻求有关 iOS 脏矩形的帮助时偶然发现此问题的任何人,我想说我解决了这个问题,这是我的错误,而不是苹果的错误。我花了一个上午做 git bisect 以缩小问题出现时的范围,并发现当我在 10 月初进行一些重构时,我向我的模型引入了一些更改通知,这些通知间接导致了 setNeedsDisplay 覆盖了我的触摸的 setNeedsDisplayInRect处理代码是费力的计算。

所以 - 不是苹果虫!

于 2013-11-15T12:55:15.613 回答