异步绘图和触摸 [英] asynchronous drawing and touches

查看:99
本文介绍了异步绘图和触摸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个绘制区域(UIView),我在CGContextRef中绘制。

当然我正在接触画画。
当drawRect方法慢慢地抽取很多现有对象时,触摸不会被捕获。

如果我在drawRect中调用另一个线程中的绘图或者使用函数dispatch_async它不会绘制,因为它有没有合适的背景。

我已经很多人去了,但一无所获。

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];
});




  • 这些事情也无济于事。

  • 我该怎么办?任何人都可以帮忙接触并大量抽取大量物品吗?

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

    推荐答案

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

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


    1. 你应该删除所有对显示的调用 setNeedsDisplay 并将其替换为 setNeedsDisplayInRect:

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

    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:.

    如果您正在绘制移动物体,请使用CoreAnimation。

    If you're drawing moving objects, use CoreAnimation.

    如果您有很多重复的对象,请使用 CGLayerRef s

    If you have a lot of repeated objects, use CGLayerRefs

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

    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()不是线程安全的。然而,你可以做的是在你的异步块中创建一个位图上下文,描边并填充它,然后将这个上下文作为CGImageRef获取,可以将其复制到CGContextRef(正在谈论的那个)到主屏幕上运行的屏幕)。它看起来像这样:

    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
    

    这篇关于异步绘图和触摸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆