asynchronous drawing and touches

放肆的年华 提交于 2019-12-05 04:33:54

问题


I have a draw area (UIView), where i draw within the CGContextRef.
Ofcourse i am catching touches to draw. While the drawRect method slowly draws lot's of existing objects the touches are not caught.
If i call drawing in drawRect in separate thread or with function "dispatch_async" it doesn't draw because it has no appropriate context.
I've seached a lot but found nothing.

dispatch_async(dispatch_get_main_queue(), ^{
    [_mainArea setNeedsDisplay];
});
  • these things do not help either.

What can i do? Can anybody help to catch touches and draw lots of objects simultainiously?


回答1:


When you're having problems keeping your graphics up to date, before you start getting into multithreading...

  1. You should remove all calls to display or setNeedsDisplay and replace them with setNeedsDisplayInRect:

  2. You should optimize your drawRect: method so that you're only redrawing the parts of the view that need it. You can get even more fancy in this method and ignore the rect argument from the method and obtain the raw rects being drawn from getRectsBeingDrawn:count:.

  3. If you're drawing moving objects, use CoreAnimation.

  4. If you have a lot of repeated objects, use CGLayerRefs

Calling setNeedsDisplay with a dispatch_async() won't make the view draw on another thread; all drawing happens in drawRect:, and drawRect: is always called by the main thread/queue.

UIGraphicsGetCurrentContext() is not thread safe. What you can do however is create a bitmap context in your async block, stroke and fill into that, and then get this context as a CGImageRef that can be comp'd into the CGContextRef (the one that's talking to the screen) running on the main thread. It would look something like this:

@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


来源:https://stackoverflow.com/questions/14606943/asynchronous-drawing-and-touches

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!