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?
Related
My question might be answered somewhere but I just couldn't find solution after a long research.
I need to draw visually shapes (curves, lines, rectangles etc.) on iPhone one on top of the previous. I did that using CGContext to draw over an image and it's working fine. However in my app the drawing view resizes on device rotation and the lines become blurred because of the different image size.
That's why I subclassed UIView and to call setNeedsDisplay from touchesMoved and touchesEnded. In drawRect I'm passing the point and... almost everything works OK.
However I have two problems:
1. Every time drawRect is called it clears previous drawing and starts over so I can't add a new shape.
2. Second is followed by same thing - I can't make a curve as on every move drawRect is called and the previous point is dismissed and a line is added from the starting point to the current.
So am I doing the whole thing wrong and is there some other better approach to this.
Thanks in advance!
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.
I drew a line on UIView. It's working properly. I did the same thing as described here : [question]:http://stackoverflow.com/questions/2595446/drawing-an-image-is-completely-out
And now I need to erase those lines. Erase means after I move my finger on the touch screen I need to erase it. Just like an eraser. How can I do it?
If you are asking to erase the whole line when the user touches it, than i don't know how you can achieve that, but if you are asking to erase the part of the line were the user touches, than you can draw a line of the color the view that you are using to draw the line on to in that way you will get the effect of an eraser.
You have to call setNeedsDisplayInRect: (UIView) to set the rectangle of the line as invalid. Only this rectangle will be redrawn until the next drawing cycle.
Make sure you have a flag in the drawRect: method you can ask for, that identifies whether the line should be drawn or not.
I would like to implement a drawing class with the help of Quartz.
I want to be able to save parts of what is drawn on separate layers. I want these layers to be retrievable, so I can delete/hide/show layers on command.
Can I save multiple CGLayerRef as a NSMutableArray property of my class and then be able to retrieve them? If yes, can you point me to an example.
If there are any flaws in the "architecture" above, please point me to alternative solutions that could help me accomplish layered control over graphs.
Thank you.
CALayers that you create, can of course be stored in NSMutableArray, and you can work with them later on, usually by animating their properties, or asking them to redraw themselves.
Usually you create a custom UIView, create and manage layers within that view. Those layers are either member variables of that view, or you store them in an array. As things are happening in your app, your view animates the layers accordingly. Usually you want to react on touch events (which you also implement in that particular view - touchesBegan/Moved...) and animate the layers.
CALayer draws itself and caches the content for as long as you call [layer setNeedsDisplay], or it's bounds (size) are changed (well, if needsDisplayOnBoundsChange is true). Practically in all my apps I did, such redrawing happens very rarely - only if data are changed, and layer needs to redraw. Animating layers, transforming their size, rotation, changing position - layer is not redrawn during any of these. Hiding, showing, changing transparency - no redraw is required.
That "drawing class" you are talking about - you actually have only two options - either you extend CALayer and overwrite drawInContext:, or you create basic CALayer, set its delegate, and there you draw in drawLayer:inContext:. I personally prefer creating delegates.
Everytime UIView's drawRect is called, the content drawn by previous drawRect (using Core Graphics) is cleared out. How can I make it so that the paths rendered from previous drawRect calls stay until I explicitly clear it?
You basically need to clip the 'dirty' part of your rect where changes have been made, and only this part will be re-drawn.
- (void)setNeedsDisplayInRect:(CGRect)invalidRect
I'm fighting this issue myself right now. The problem is there is a property on the UIView called "clearsContextBeforeDrawing" that according to the documentation is supposed to fix this problem, however it doesn't work that way in my experience.
I think ultimately the solution to this is going to be to allocate an offscreen buffer and do all my drawing there, then blt it over to the UIView in the drawRect method.
I'm pretty certain there's no way around this; it's how UIView is designed to work. If asked to, your custom view should be able to draw any part of itself at any time. This is partly because views can do more than just appear onscreen. e.g. on the desktop they can be printed, and even on the iPhone, you might wish to capture the contents of a view to a bitmap.