Асинхронное рисование и касания
У меня есть область рисования (UIView), где я рисую в CGContextRef.
Конечно, я ловлю прикосновения к рисованию. Хотя метод drawRect медленно рисует множество существующих объектов, прикосновения не улавливаются.
Если я вызываю рисование в drawRect в отдельном потоке или с помощью функции "dispatch_async", оно не рисует, потому что не имеет соответствующего контекста.
Я много искал, но ничего не нашел.
dispatch_async(dispatch_get_main_queue(), ^{
[_mainArea setNeedsDisplay];
});
- эти вещи тоже не помогают.
Что я могу сделать? Кто-нибудь может помочь поймать прикосновения и рисовать много объектов одновременно?
1 ответ
Когда у вас возникают проблемы с обновлением графики, прежде чем вы начнете заниматься многопоточностью...
Вы должны удалить все звонки на
display
или жеsetNeedsDisplay
и заменить ихsetNeedsDisplayInRect:
Вы должны оптимизировать свой
drawRect:
метод, так что вы перерисовываете только те части представления, которые в этом нуждаются. Вы можете получить еще больше фантазии в этом методе и игнорироватьrect
аргумент от метода и получить необработанные ректы, взятые изgetRectsBeingDrawn:count:
,Если вы рисуете движущиеся объекты, используйте CoreAnimation.
Если у вас много повторяющихся объектов, используйте
CGLayerRef
s
призвание setNeedsDisplay
с dispatch_async()
не заставит представление рисовать на другой нити; все рисование происходит в drawRect:
, а также drawRect:
всегда вызывается основным потоком / очередью.
UIGraphicsGetCurrentContext()
не является потокобезопасным. Однако вы можете создать растровый контекст в своем асинхронном блоке, обвести его и заполнить, а затем получить этот контекст в виде 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