在 iPhone 上使用 Quartz 时如何保留之前的绘图?
Posted
技术标签:
【中文标题】在 iPhone 上使用 Quartz 时如何保留之前的绘图?【英文标题】:How to keep the previous drawing when using Quartz on the iPhone? 【发布时间】:2010-09-28 19:41:54 【问题描述】:我想在 iPhone 上通过触摸并在屏幕上拖动来画一条简单的线。我设法通过继承 UIView 并更改默认的 drawRect: 方法来做到这一点。同时在我的视图控制器中,我检测到触摸事件并在必要时调用 [myView setNeedsDisplay]。问题是当我尝试绘制第二条线时,前一条线消失了。有没有办法在屏幕上保留上一行?
我们将不胜感激任何输入。
【问题讨论】:
【参考方案1】:通常的方法是使用CGBitmapContextCreate()。在 -init/-init-WithFrame:/etc 中创建它并在 -dealloc 中调用 CGContextRelease()。我不确定您如何使用 CGBitmapContextCreate() 处理“视网膜显示”的 2 倍比例。
(UIGraphicsBeginImageContext() 更简单,但做UIGraphicsBeginImageContext(); myContext = CFRetain(UIGraphicsGetCurrentContext()); UIGraphicsEndImageContext();
可能不安全。)
然后做类似的事情
#import <QuartzCore/CALayer.h>
-(void)displayLayer:(CALayer*)layer
UIGraphicsPushContext(mycontext);
... Update the bitmap context by drawing a line...
UIGraphicsPopContext();
CGImageRef cgImage = CGBitmapContextCreateImage(mycontext);
layer.contents = (id)cgImage;
CFRelease(cgImage);
为了提高效率,我使用了-displayLayer:
(一个 CALayer 委托函数;一个 UIView 是它的层的委托)而不是 -drawRect:
:如果你使用 -drawRect:
,CALayer 会创建一个 second 上下文(因此是位图的第二个副本)。
或者,您可能对 CGLayer 有好运。我从未见过使用它来代替位图上下文的理由;它可能在某些情况下更有效。
或者,您可能可以摆脱设置self.clearsContextBeforeDrawing = NO
,但这很可能会中断。 UIKit(或更准确地说,CoreAnimation)希望您绘制包含在剪辑 rect 中的整个视图(这是-drawRect:
的“rect”参数;不保证是边界)。如果您的视图离开屏幕,CoreAnimation 可能会决定它想要返回内存。或者 CoreAnimation 可能只绘制屏幕上的视图部分。或者 CoreAnimation 可能会进行双缓冲绘图,导致您的视图看起来在两种状态之间翻转。
【讨论】:
【参考方案2】:如果你使用drawRect:来绘制,那么你需要绘制整个区域。因此,您不仅需要存储最新部分的数据,还需要存储所有内容。
作为替代方案,您可以直接在位图中绘制,或为线条动态生成子视图(仅对非常有限的绘图有意义(即一些基于矢量的东西)。
【讨论】:
以上是关于在 iPhone 上使用 Quartz 时如何保留之前的绘图?的主要内容,如果未能解决你的问题,请参考以下文章
我在 iPHone 上的 Quartz 绘图在旋转后被剪掉了!
iPhone开发中如何制作这种动画效果? Quartz 2d,Vore 动画?