异步绘图和触摸

Phe*_*erg 3 objective-c uiview drawrect ios

我有一个绘制区域(UIView),我在CGContextRef中绘制.
当然,我正在接触画画.虽然drawRect方法慢慢地抽取大量现有对象,但触摸不会被捕获.
如果我在单独的线程中调用drawRect中的绘图或使用函数"dispatch_async"调用绘图,则它不会绘制,因为它没有适当的上下文.
我已经进行了很多搜索,但一无所获.

dispatch_async(dispatch_get_main_queue(), ^{
    [_mainArea setNeedsDisplay];
});
Run Code Online (Sandbox Code Playgroud)
  • 这些东西也无济于事.

我能做什么?任何人都可以帮助抓住接触并同时绘制大量物品吗?

ilu*_*pra 8

当您在开始进入多线程之前,在保持图形最新时遇到问题...

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

  2. 您应该优化drawRect:方法,这样您只需重新绘制需要它的视图部分.您可以在此方法中获得更多花哨,并忽略方法中的rect参数并获取从中提取的原始rects getRectsBeingDrawn:count:.

  3. 如果要绘制移动对象,请使用CoreAnimation.

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

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

UIGraphicsGetCurrentContext()不是线程安全的.然而,您可以在异步块中创建一个位图上下文,描边并填充它,然后将此上下文作为CGImageRef获取,该CGImageRef可以复制到CGContextRef(与屏幕通话的那个)上运行主线程.它看起来像这样:

@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
Run Code Online (Sandbox Code Playgroud)