我正在制作放大镜应用程序,允许用户触摸屏幕并移动他的手指,将有一个带有手指路径的放大镜。我通过截屏并将图像分配给放大镜图像视图来实现它,如下所示:
CGSize imageSize = frame.size;
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextScaleCTM(c, scaleFactor, scaleFactor);
CGContextConcatCTM(c, CGAffineTransformMakeTranslation(-frame.origin.x, -frame.origin.y));
[self.layer renderInContext:c];
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenshot;
问题是self.layer renderInContext
很慢,因此用户在移动手指时感觉不平滑。我尝试在其他线程中运行self.layer renderInContext
但是,它使得放大镜图像看起来很奇怪,因为放大镜中的图像显示延迟。
有没有更好的方法将视图渲染到图像中? renderInContext:
使用GPU吗?
答案 0 :(得分:81)
没有。在iOS6中,renderInContext:是唯一的方法。这很慢。它使用CPU。
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
view.layer
,用于捕捉动画的最终帧。view.presentationLayer
,它捕获动画的当前帧。 UIView *snapshot = [view snapshotViewAfterScreenUpdates:YES];
contents
是不可变的。如果你想申请效果,那就不好了。[view resizableSnapshotViewFromRect:rect afterScreenUpdates:YES withCapInsets:edgeInsets]
snapshotViewAfterScreenUpdates:
相同,但具有可调整大小的插入内容。 content
也是不可变的。 [view drawViewHierarchyInRect:rect afterScreenUpdates:YES];
renderInContext:
快。 有关新快照API的信息,请参阅WWDC 2013 Session 226 Implementing Engaging UI on iOS。
如果有任何帮助,这里有一些代码可以在一个仍在运行时丢弃捕获尝试。
这会限制一次阻止执行一个块,并丢弃其他人。来自this SO answer。
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
dispatch_queue_t renderQueue = dispatch_queue_create("com.throttling.queue", NULL);
- (void) capture {
if (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW) == 0) {
dispatch_async(renderQueue, ^{
// capture
dispatch_semaphore_signal(semaphore);
});
}
}
这是做什么的?
DISPATCH_TIME_NOW
表示超时为none,因此在红灯时立即返回非零值。因此,不执行if content。