iPhone-试图找出drawRect:

iPhone-试图找出drawRect:,iphone,Iphone,我有我的这个应用程序,它包含一个部分,允许用户在屏幕上进行简单的绘画。我的想法是提供两种绘画:粗糙和光滑(贝塞尔)线条 构建方式:我有一个带有自定义drawRect方法的透明UIView。我不确定我是否完全理解drawRect,但代码部分工作正常 工作原理:用户在屏幕上移动手指。当他第一次触摸屏幕时,TouchesStart创建一个名为myPoints的可变数组,并存储第一个点的坐标,并按原样存储画布(以允许撤消) 之后,TouchesMoved例程将获取所有点并将它们添加到myPoints。如

我有我的这个应用程序,它包含一个部分,允许用户在屏幕上进行简单的绘画。我的想法是提供两种绘画:粗糙和光滑(贝塞尔)线条

构建方式:我有一个带有自定义drawRect方法的透明UIView。我不确定我是否完全理解drawRect,但代码部分工作正常

工作原理:用户在屏幕上移动手指。当他第一次触摸屏幕时,TouchesStart创建一个名为myPoints的可变数组,并存储第一个点的坐标,并按原样存储画布(以允许撤消)

之后,TouchesMoved例程将获取所有点并将它们添加到myPoints。如果用户选择绘制贝塞尔线,则需要此阵列

当检测到touchesEnded时,应用程序必须查看用户是在绘制规则线(粗线)还是在绘制贝塞尔曲线。如果不是bezier,则已绘制线。如果需要贝塞尔曲线,我需要擦除画布,恢复画布在Touches开始存储时的状态,计算新的贝塞尔近似值(反向设计为适合绘制点的最佳贝塞尔曲线),然后绘制新曲线,替换粗糙曲线

这些是我的问题:

1) 如何存储撤销?我最初考虑创建一个新的层来存储撤销,但这样做会将应用程序内存使用量从8 Mb增加到13 Mb。。。我不确定这是否是一个安全使用级别(该应用程序兼容3GS、iPodtouch 2nd G及以上,包括iPad)。然后,我决定启动一个队列操作来保存画布。这将导致保存空白图像(我假设保存方法的上下文为nil,因为它无法获取drawRect之外的上下文)

2) 第二个问题与第一个问题类似。此时,我需要将画布恢复到保存时的状态,但由于restore方法在drawRect之外,因此它也会将上下文设置为nil

touchesBegind、TouchesMoved和toucheseEnd以及提到的所有方法都在drawRect所在的同一类中,而不是在viewController中

我的问题是:你们会怎么做

我在商店里看到一个绘画应用程序提供多级撤销。我无法想象他们是怎么做到的,因为在我的第一次尝试中,我创建的层消耗了5MB的内存,所以看起来不可能有这样的撤销

请帮帮我。。。我绝望了


谢谢

为什么要存储“画布”?(我想这就是你画的图像,对吗?)

我认为您要做的是将可绘制对象(粗线、贝塞尔等)存储在某个对象中,该对象具有“路径”中的所有点,然后您就有了一个集合(即nsmutablearray)和所有可绘制对象。。。。然后drawRect获取该集合并将其绘制到屏幕上

可以实现撤消,因此当用户想要撤消时,可以从集合中删除最后一个可绘制对象或添加到集合中的最后一个点并重新绘制

您无法在drawRect之外获取绘图上下文,但您需要做的只是更新数据结构(点、可绘制对象等),并通过调用[self-setNeedsDisplay]使控件“无效”,以便操作系统调用您的drawRect,然后您可以在屏幕上绘制对象

编辑:

我创建了一个简单的概念验证应用程序(在c#winforms中…我现在无法访问我的mac,但它足够简单,可以理解这个概念),它以这种方式工作。示例代码位于

请注意,如果您变得更复杂,则此概念有几个限制,例如,如果您根据手指移动的速度对线条的宽度产生了幻想,则重绘不会处理此问题,尽管您可以向可绘制对象添加更多属性以解释更多幻想

如果需要,我会将样本移植到iOS


希望这有帮助。

好的。请稍候。。。我正在努力理解你上面所说的。。。我最初以为我会回答得很好。。。因为我以前也做过类似的事情。但是后来我读了詹姆的整个问答,这让我很困惑。。但不管怎么说,从我的理解。。我可以给你一个答案

所以对于擦除部分。。我是在我的点阵列的帮助下画的,u存储在触摸开始和移动。。。我想你只是在画那样的画。。所以对于擦除。。我立刻清空了我的点数组,然后调用“setNeedsDisplay”。。这将在数组中找不到任何点,因此将清除所有

如果在粗略绘制时不使用数组绘制,那么我建议您这样做

我还要推荐一件事。。确定用户想要粗糙或平滑的曲线应该在开始时进行,而不是在“触摸”状态下进行。。然后用数组相应地画

我希望你知道如何画粗糙的曲线,对于光滑的曲线,我会给你一个链接到我的答案


(是的,我所说的画布是指图像)。。。这个问题是橡皮擦。用户可以用手指擦除部分对象。如果用户擦除部分线条(已存储的点),我将不得不重新创建擦除。这不是很愚蠢吗?这些物体会被一次又一次地全部或部分地绘制和擦除,直到获得最终的图像。我不认为这是最好的选择。实际上,擦除只是集合中的另一个绘图对象,但使用背景色(可能与…不同)。。。您只需在撤消某些操作(即删除最后一项)时从集合中重新创建图像。所有其他操作都保存在Simone visible Images中对不起,上面的输入错误。。。我的Ipad在捉弄我。。。。我用一个链接更新了答案,链接到了一个概念验证示例,谢谢。就这样。您的答案与iphone_bharat的结合使其成为一个强大的解决方案。