iPhone Core Graphics Animations - iphone

Is it possible to animate something that you have drawn using core graphics in a UIView's drawRect method?
Say for example I have created a zigzag line by stroking a path. What if I want to animate something like the position of an individual point in that path? If my UIView has the properties animatedPointX and animatedPointY which are used to draw my point, can I somehow animate my zigzag line by changing these properties? Is something like this possible with Core Graphics?
Every animation example and tutorial I have found deals with animating an entire view as a whole. I cant seem to find anything about animating custom properties of your drawing/layer.

If you want to animate the graphics that you draw in drawRect:, you need to periodically update the variables that control what you draw and send setNeedsDisplay to the view.
Apple recommends using a CADisplayLink object to periodically notify yourself that it's time to update and redraw.
You can see an example of the use of CADisplayLink to trigger the update and setNeedsDisplay in the ARView.m file of the pARk sample app.

Related

Drawing to the screen

I just want to draw point and line as per finger touch and moved in iphone screen.
What is the best way to draw point in iphone?
Can anyboday tell me how to draw point as per finger touch and moved in iphone ?
Thanks,
You can't "just draw" on the screen. Closest approximation might be to save some coordinates from some view's touch delegate methods and call setNeedsDisplay. When the view's drawRect is called, you can then use some Core Graphics (CG) drawing commands with those saved coordinates into the given drawing context. The OS will shortly then composite that view context onto the display screen.
check with this tutorial,i am sure it will definetly help you.
http://mobile.tutsplus.com/tutorials/iphone/ios-sdk_freehand-drawing/
you can draw line on Image or on UIView using UIBezierPath class.. in this class object you can store the user touch points and draw line using this points array..
for more details see the tutorial and demo from this link..
Drawing on View and Image

How can I implement undo functionality in my painting application for iOS?

I developed a painting application for iPad. I have tried in many ways to implement undo functionality in my app, but I couldn't. I tried to save every drawing object as an image by capturing the screen in the touchesEnd: method. I can save all these drawn objects in an array and while doing undo I can display the previous drawn object image by adding it as a subview of my drawing view. Until now, it has been working fine, but after adding that image to my view I couldn't draw any more. I have enabled the userInteraction property for the ImageView, also, but I still couldn't draw.
How can I change that ImageView to allow drawing after doing undo?
One option is to create core data objects for your drawing operations and then use the core data undo manager.
Have a look here:
http://www.mikeabdullah.net/core_data_undo_management.html

Draw a straight line and have it refresh if UIImageView is moved

How can I draw a straight line between two UIImageViews and have the line "refresh" if one of the views is moved. I assume I'll have to use NSNotificationCenter, but other then that I'm a bit stuck.
Thanks for your help!!!
A good way to do this would be to use KVO (Key-Value Obverving).
If you use KVO to watch for changes in the bounds (or frame) of the views, you will get notified about position changes, at which point you can (re-)render a line on the display.
More about KVO: https://stackoverflow.com/questions/1470167/is-there-any-tutorial-out-there-on-key-value-coding-and-key-value-observing
As for rendering a line: one often used technique is to write a subclass of UIView in which you override the drawRect method and draw a line using Core Graphics. See this question: How do I draw a line on the iPhone?

Caching Quartz Rendered Drawing Into CALayer

I'm in the process of trying to tweak the process of a game which uses Quartz to draw a moderate number of sprites, around 50, during each game loop (40 fps).
At the moment I have a very simple drawing mechanism where a single game view (UIView) iterates over all the active sprites and asks each one to render itself to a CGContext (that of the view). This works fine, but performance is starting to drop with more than 50 active objects and I'd quite like to tweak things.
I've decided that holding a CALayer for each sprite which its cached drawing is the way to go - then using Core Animation to render/rotate/scale the drawing.
I'm struggling to understand how I achieve this. Where exactly do I initially draw to? I don't have a CGContext when my sprite is initialised. Is the right approach to render to a CGImage as a buffer then set it as the content on the CALayer?
Just subclass CALayer and do your drawing in drawInContext:. The layer will then cache its contents automatically. If you don't want to subclass CALayer, you can also assign it a delegate (which must not be a UIView) and implement drawLayer:inContext:.

Optimizing a drawing (with finger touches) application for iPhone SDK

I'm writing an application that uses your finger to draw simple diagrams. I have it working for the most part but now I'm trying to optimize its performance. When the user swipes their finger fast, I can't capture enough touch events to draw a smooth path.
Here's my current approach:
1) I subclassed a UIView and added a poroperty to a CGLayer (gets created lazily and is the same size as my UIView).
2) My UIView subclass responds to touch events by storing the current and last touch points in instance variables.
3) My view's setNeedsDisplay is called and in the draw rect , do the following:
- draw a line from the previous touch location to the current touch location to the CGLayer
- draw the entire CGLayer to my views context in one go
The main problem is when a user swipes fast I get relatively few touch events, so the lines I draw between the touches are long and makes the path look jagged not smooth.
My questions:
1) Does drawRect (on my UIView subclass) and my touch event handlers on my UIView subclass get called in the same thread? I.e. could I have to threads executing (one in a touch event and the second in my draw rect)?
If no - do touch events get queued up while drawRect is being called? And how can I improve performance - simply improve performance of drawRect?
If yes - how can I get more touch events to happen so I can draw a smoother path?
Thanks.
Another approach is to interpolate the curve between the sample points. When the finger drag starts, begin collecting sample points. As the number of points increase, redraw the line. With two points, draw a straight line, with three or more draw a curve. You can re-start the process when two points are sampled that lie within a defined distance. This would allow you to draw two arcs (like a 'm') in one motion - you naturally pause in the middle as you change direction, possibly long enough for two or more samples.
drawRect gets called on the main thread. But you don't have to do this. You can use the main thread to collect UI events and do the drawing on a background thread. The background thread gets notified whenever there are new touches and starts a drawing operation in its own CGBitmapContext. Then you create a CGImage and hand it over to the View: view.layer.contents = drawingImage.
If you need even more performance, consider drawing using OpenGL.
Aloo, did you have find a solution to his as I've got the same problem. I also found agreat tutorial http://www.ipodtouchfans.com/forums/showthread.php?t=132024 but it also has the same problem that if you draw fast, say a circle, the drawing isn't very smooth. It;s almost like the iPhone just can't keep up, unfortunately this has to use the core graphics stuff.
Have you tried this?
http://developer.apple.com/library/ios/#samplecode/GLPaint/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007328-Intro-DontLinkElementID_2
I tried adding
CGContextSetLineJoin(UIGraphicsGetCurrentContext(), kCGLineJoinRound);
but this did nothing. Looks like we'll have to figure out bezier curves