【问题标题】:Using setNeedsDisplayInRect still erases the underlying content使用 setNeedsDisplayInRect 仍然会擦除底层内容
【发布时间】:2012-04-08 19:48:01
【问题描述】:

我将 UIView 子类化并覆盖了 touchesBegan、touchesMoved、touchesEnded 和 drawRect 方法,以创建一个允许用户通过触摸屏幕进行绘图的应用。我正在使用 Quartz 2D 库来绘制图纸。

在 touchesBegan、touchesMoved 和 touchesEnded 中,我会跟踪触摸事件的当前和先前位置。每次触摸移动和触摸结束时,我都会使用包含触摸的先前和当前位置的最小矩形调用 setNeedsDisplayInRect,以保留底层绘图。 (我希望所有图纸像图层一样相互叠加。)

我注意到一个奇怪的伪影:当创建一个与另一个绘图重叠的绘图时,Quartz 会重新绘制传递给 setNeedsDisplayInRect 的矩形,但会擦除该矩形下方的所有内容。

我怀疑问题出在混合模式上,但是我尝试了多种不同的混合模式,但似乎都没有效果。

如何绘制保留底层内容的路径?

【问题讨论】:

    标签: ios drawing touch quartz-2d


    【解决方案1】:

    Quartz 不是画布模型。它不跟踪以前循环中绘制的内容。每次调用drawRect: 时,您有责任处理所传递的矩形中的每个像素。默认情况下(设置在UIView clearsContextBeforeDrawing),Quartz 会为你清除矩形,但每次绘制内容是你的工作。

    如果要对事物进行分层,则需要将每个事物放在自己的 CALayerUIView 中,或者每次调用 drawRect: 时都需要重新绘制任何重叠部分。

    【讨论】:

    • 嗯,在文档中,它说“Quartz 2D 使用画家的模型进行成像。在画家的模型中,每个连续的绘图操作都会将一层“绘画”应用于输出“画布”,通常称为页面。”
    • 正确。每次致电drawRect:。在下一次致电drawRect: 时,您将获得一个全新的画布。当我说 Quartz 没有“画布”模型时,我指的是 HTML5 开发人员倾向于期望的那种持久画布。
    • 请注意,实现这种持久画布的另一种方法是绘制到图像上下文中,然后在drawRect:期间仅绘制图像上下文
    • 我明白了,所以即使我正在调用 setNeedsDisplayInRect,因为 drawRect 没有跟踪正在重绘的矩形中的底层状态,底层内容也会被删除。我也一直在绘制当前的上下文。
    • 正确。如果需要,您可以自行维护状态。
    猜你喜欢
    • 1970-01-01
    • 2012-08-11
    • 2018-11-20
    • 2018-03-11
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-06
    相关资源
    最近更新 更多