异步绘图和触摸 [英] asynchronous drawing and touches
问题描述
我有一个绘制区域(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];
});
- 这些事情也无济于事。
-
你应该删除所有对
显示的调用
或setNeedsDisplay
并将其替换为setNeedsDisplayInRect:
我该怎么办?任何人都可以帮忙接触并大量抽取大量物品吗?
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...
您应该优化 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 CGLayerRef
s
使用 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屋!