3

我有一个绘制区域(UIView),我在 CGContextRef 中绘制。
当然,我正在捕捉绘画。虽然 drawRect 方法会缓慢地绘制大量现有对象,但不会捕捉到触摸。
如果我在单独的线程中或使用函数“dispatch_async”在 drawRect 中调用绘图,它不会绘制,因为它没有适当的上下文。
我搜索了很多,但一无所获。

dispatch_async(dispatch_get_main_queue(), ^{
    [_mainArea setNeedsDisplay];
});
  • 这些东西也无济于事。

我能做些什么?任何人都可以帮助捕捉触摸并同时绘制大量物体吗?

4

1 回答 1

8

当您在保持图形更新时遇到问题时,在开始使用多线程之前...

  1. display您应该删除所有对or的调用setNeedsDisplay并将其替换为setNeedsDisplayInRect:

  2. 您应该优化您的drawRect:方法,以便您只重绘视图中需要它的部分。您可以在此方法中获得更多幻想,并忽略该方法中的rect参数并获取从中提取的原始矩形getRectsBeingDrawn:count:

  3. 如果您正在绘制移动对象,请使用 CoreAnimation。

  4. 如果您有很多重复的对象,请使用CGLayerRefs

setNeedsDisplay用 a调用dispatch_async()不会使视图在另一个线程上绘制;所有绘图都发生在 中drawRect:,并且drawRect:总是由主线程/队列调用。

UIGraphicsGetCurrentContext()不是线程安全的。然而,你可以做的是在你的异步块中创建一个位图上下文,描边并填充它,然后将这个上下文作为一个 CGImageRef 获取,它可以被编译到运行在主线程。它看起来像这样:

@implementation BGDrawingClass : UIVew {
    CGImageRef bgImage;
}

-(void)prepBGImage {

CGRect rect = TheRectISpendALotOfTimeIn();
dispatch_async(_myBGQueue,^{

        CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
        CGContextRef ctx = CGBitmapContextCreate(nil, rect.size.width, rect.size.height, 8, rect.size.width * (CGColorSpaceGetNumberOfComponents(space) + 1), space, kCGImageAlphaPremultipliedLast);
        CGColorSpaceRelease(space);

        /* do expensive drawing in this context */

        bgImage = CGBitmapContextCreateImage(ctx);

        dispatch_async(dispatch_get_main_queue(),^{ 
             [self setNeedsDisplayInRect:rect];
        });
    });
}

-(void)drawRect:(NSRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    /* do drawing behind this ... */
    if (CGRectIntersectsRect(rect, TheRectISpendALotOfTimeIn()) {
        CGContextDrawImage(ctx, TheRectISpendALotOfTimeIn(), bgImage);
    }
    /* do drawing in front of this */
}
@end
于 2013-01-30T18:21:40.923 回答