iPhone: Rotating a drawing without rotating the view within which it is drawn - iphone

Anyone who has gone through the Stanford CS193P class on iTunes will recognize this from Assignment 3 (HelloPoly). For those not familiar:
I have a custom view called polyView, an instance of PolygonView, a subclass of UIView. On this view, I use CGContextDrawLinearGradient to paint a color gradient over the entire rectangular view. Then I use CGContextDrawPath to stroke and fill a polygon within the bounds of polyView. And I have a UILabel called nameLabel in the center of the view (and polygon) that displays the name of the polygon (triangle, quadrilateral, pentagon, etc.). All of this works fine, and the code to do all this is in the -(void)drawRect method of the PolygonView class.
Where I ran into trouble is with an additional requirement to rotate the polygon within the view in response to user gestures. I used CGAffineTransformRotate() in response to touchesBegan() and touchesMoved() events within the PolygonView class, and this basically works, too. But I can only rotate the entire polyView, not just the polygon drawn on it. I'm sure I could go back and recalculate the path of the polygon and redraw/fill the path in response to each touchesMoved() event, but that would be expensive and can't be the best method. How can I use CGAffineTransformRotate to rotate just the polygon, without rotating the gradient-filled view or the label in the center?
Or is there some way to create the polygon on a layer that I can place over the background polyView at the desired rotation angle?
Thanks for any help you can give a beginner here!
Duane

You can do a CGContextSaveGState(...) just before doing the rotation transformation, then drawing the polygon and restoring the drawing state with a CGContextRestoreGState(...) afterwards, so as not to affect any other drawing in the view later.

Related

How to get the correct frame of a rotated UIView (including correct position)

I have an app where I have a rectangle that the user can rotate and pan using their fingers. I'd simply like to know what the frame is of this rotated view so I can find out if it intersects another rectangular UIView (can't use the frame property because it gets invalidated when the UIView gets transformed). What's the easiest way to accomplish this?
Every UIView has a property frame which is of type CGRect.
You can access it using view.frame.
After the transform is applied you can use the bounds and center property on the view to get the orientation. It may take a little bit of calculation but i hope you can get to it easily.
Refer to this image from an answer to this question.

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

Can we Add a new layer over CATiledLayer?

I am displaying a big image in CATiledLAyer.
Now i want to draw a line between two points where the user touches on that image.
Would that be possible ?? , if so can you outline me the way to accomplish it ??
Thanks,
Ratna
I did something similar for an app a while back. The strategy I used was to place another view on top of the view with the tiles. Then set your self up as a UIScrollViewDelegate and everytime the tiled view scrolls or zooms, recalculate where the overlayed objects need to be. Just read the contentOffset value and the zoomScale and you should have what you need to correctly figure out where your overlay needs to be positioned. You will also have to make sure that touches are correctly reaching the tile view if they have to pass through your overlay view.

Drawing where touch is detected

How can pixels be drawn at a touch location?
If the user touches a certain area of a view, how are the locations used to draw/mark the location with e.g black color?
What kind of view is this or how is this drawing done?
Generally, if you're using Quartz you'll:
handle your touch events
store the points that are streaming in in some datastructure
invalidate your view so it draws
override drawRect and draw the points you stored in 2.
UIBezierPath is a class that can help with this. You can essentially "draw into" an instance of UIBezierPath when you receive the touch events, then render the object in drawRect.

Apply barrel distortion to UIView

I've got a UIScrollview which fills a landscape screen, which contains a small tree of UIViews around inside it which I can scroll horizontally. I'd like to apply a barrel distortion to the scrollview, so that as the subviews move from the outside to the centre of the scrollview, they change shape.
What is a good what to go about applying distortions like this?
Is there a way to override drawRect for the scroll view, draw onto a bitmap, distort it, then draw that to the ScrollView's context instead? Or are there built in APIs to do this sort of distortion?
(source: arielnet.com)
You could get close to this effect by properly transforming the layers for each of your UIViews. Using a CATransform3D, you can rotate and translate each of the layers in 3-D, as well as apply a perspective effect. For your case, you can translate each of your UIView layers so that they are like a carousel, with the middle view forward and straight-on to the screen, and the side layers tilted and recessed slightly from the screen. This would not cause a curvature of the layers themselves (they will still be drawn as rectangles), but if you apply a transform on the main view's layer to create a perspective effect you should be able to get very close.
For an example of this kind of 3-D positioning of layers, I recommend this example where a full 3-D maze is constructed out of CALayers.
As far as the scroll view goes, you probably will have to do custom touch handling for this. You might be able to get by with respinding to the UIScrollViewDelegate methods like scrollViewDidScroll:, but I've not tried this myself.