【问题标题】:How to keep the previous drawing when using Quartz on the iPhone?在 iPhone 上使用 Quartz 时如何保留之前的绘图?
【发布时间】:2010-09-28 19:41:54
【问题描述】:

我想在 iPhone 上通过触摸并在屏幕上拖动来画一条简单的线。我设法通过继承 UIView 并更改默认的 drawRect: 方法来做到这一点。同时在我的视图控制器中,我检测到触摸事件并在必要时调用 [myView setNeedsDisplay]。问题是当我尝试绘制第二条线时,前一条线消失了。有没有办法在屏幕上保留上一行?

我们将不胜感激任何输入。

【问题讨论】:

    标签: iphone uiview quartz-2d


    【解决方案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:来绘制,那么你需要绘制整个区域。因此,您不仅需要存储最新部分的数据,还需要存储所有内容。

      作为替代方案,您可以直接在位图中绘制,或为线条动态生成子视图(仅对非常有限的绘图有意义(即一些基于矢量的东西)。

      【讨论】:

        猜你喜欢
        • 2011-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-08
        • 2010-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多