开发者

iPhone - trying to figure out the drawRect:

I have this app of mine that contains a section that will allow the user to do simple paintings on the screen. My idea is to offer two kind of painting: rough and smooth (bezier) lines.

How it is built: I have a transparent UIView with a custom drawRect method. I am not sure if I understood drawRect completely, but the code is partially working.

How it works: the user moves the finger around the screen. When he first touches the screen, TouchesBegan creates a mutablearray called myPoints and store the coordinate of the first point and stores the canvas as it is (to allow undo).

After that, TouchesMoved routine grabs all points and adds them to myPoints. This array is needed in the case the user chooses to draw bezier lines.

When touchesEnded is detected, the app has to see if the user was painting a regular line (rough) or a bezier. If it was not bezier, the lines are already drawn. If a bezier is needed, I need to erase the canvas, re开发者_Go百科store the canvas as it was when TouchesBegan stored it, calculate the new bezier approximation (reverse engineered to be the best bezier curve to fit the drawn points) and draw the new curve, replacing the rough one.

These are my problems:

1) How to store the undo? I first thought on creating a new layer to store the undo, but doing that increased the app memory usage from 8 to 13 Mb... I am not sure if this is a safe level to use (the app is compatible with 3GS, iPod Touch 2nd G, and up, including iPad). Then, I decided to fire a queue operation to save the canvas. This is resulting in blank images being saved (I suppose the saving method is getting nil for the context, because it cannot get the context outside the drawRect).

2) the second problem is similar to the first one. At this point I need to restore the canvas to what it was when it was saved, but as the restore method is outside the drawRect it it getting nil to the context too.

TouchesBegan, TouchesMoved and TouchesEnded and all methods mentioned are inside the same class where the drawRect is, not in the viewController.

My questions is: how do you guys would do that?

I saw a painting app on the store offering multi level undo. I cannot imagine how they did that, because in my first try, for ever layer I created I was consuming 5 Mb of memory, so it appears impossible to have that kind of undos...

please, help me... I am desperate!

thanks


Any reason why are you storing the "canvas"? (I think that would be the image that you're drawing right?)

I think what you want to do is store the drawable objects (rough lines, bezier, etc.) in some object that has all the points in the "path" and you then have a collection (ie a nsmutablearray) with all your drawable objects.... then the drawRect takes that collection and draws it to the screen.

Undo could be implemented so when the user wants to undo, you remove the last drawable object from the collection or the last point added to the collection and redraw...

You cannot get the drawing context outside the drawRect, but all you need to do, is update your data structure (the points, drawable objects, etc.) and "invalidate" your control by calling [self setNeedsDisplay] so the OS call you're drawRect and then you can draw your objects onto the screen.

EDIT:

I created a simple proof of concept app (is in c# winforms... I don't have access to my mac right now, but is simple enough to understand the concept) that works this way. The sample code is at

https://github.com/jaimedp/DrawEraseUndo

Note that this concepts have several limitations if you get more complex, for example, if you get fancy with the withs of the lines depending on the speed of the finger movement, the redrawing does not handle this, although you could add more properties to the drawable object to account for more fanciness.

I'll port the sample to iOS if needed.

Hope this helps..


OK .hold on ... I am trying to get what u said above ... I initially thought I would answer it well ... because I have done something like that before ..but then I read ur whole question and answer by Jaime and it confused me a lot .. but anyways from what I interpret .. I can give u an answer

So for the part of erasing .. I was drawing with the help of my array of points that u stored in touches began and moved ... I think u r drawing like that only .. so for erasing .. i momentarily emptied my array of points and then call "setNeedsDisplay".. which will find no points in array and hence will clear all...

If u r not drawing with array in case of rough drawing , then I would recommend doing that .

I would also recommend one more thing .. that determining that user wants rough or smooth curves should be done in the beginning and not on "touchesEnded".. and then draw accordingly with array ...

I hope u know how to draw rough curves and for smooth curves I will give u a link to my answer

CGContext Draw Line slowly responding to fast finger movement

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜