How can i rotate an arrow image by touch on that image? - iphone

I am working on a project where i need to rotate an image by touching it.
It can be rotate faster or slower depending on how the user touches it.
Can you show me some tutorials or how this can be done?

Place your image within a UIImageView, then either subclass that view and replace touchesBegan:withEvent: or set a delegate for it and implement the same method as a delegate method. This will give you the ability to respond to touch events (the beginning of a touch, in this case, although you can do the same for ending a touch or moving of the finger).
Within this touch handling method, you can implement something similar to what I describe here in order to perform a Core-Animation-enabled rotation of your UIImageView at a given speed. To alter the speed, change the duration property on the animation I provide. As I suggest there, you may want to look into a CAKeyframeAnimation to do a smoother animation with acceleration and deceleration at the beginning and end.

An easier way is to set up an NStimer and rotate the transform everytime it fires.
I've some sample code here that coincidentally does something similar:
http://github.com/kailoa/touchsamplecode/tree/master

Using Cocos2d, you can't have 'touch enabled' sprites, 'isTouchEnabled' is at the Layer level. You'll have to receive the touch at the layer level, then check the location of the touch against the location of the touchable sprite. The CGRect* functions include a 'rect contains point' which you can pass the touch location to, with the sprite's rect to see if it was 'touched', and which point you could then say [sprite runAction:[Rotate ....]]

Related

how to detect touch which appear on the location greater than resolution of device

I'm looking for help. I'm trying to make some puzzle game and I have thin scrollable layer at the bottom of my main layer which contains some puzzle shapes. I can scroll the layer and see every shape but shapes were positioned manually in code on the scrollable layer and the problem is, if I try to detect if I touched on sprite, which position is greater than 1024(in first iPad) it doesn't work. it doesn't work because touch can have position inside 1024X768 and the position of shape is for example 1500x100. to make it clearer, shapes are sprites and i try to detect them using CGRectContainsPoints method. Is there any other way to make it or have you any ideas? thanks in advance :]
What you could do is subclass your sprite, create a delegate for it and assign your main view/class as the delegate.
Implement the appropriate touch method, and send the message of what sprite was selected to your delegate (Main view or desired controller class).
With this every sprite has the same delegate, and sends a message to your controlling class as to what sprite has been selected and continue with desired functionality. No need for CGRectContainsPoint method.
This is cleaner, and more efficient.
Hope this helps!

How can I get notified with continous touch down events from my button instead only one?

I must rotate an image but I can't use the gestures or the slider, so I have thinked about using 2 buttons, one for clockwise rotation and the other for couterclockwise rotation of my UIImageView.
But I'm getting notified only one time for touch down event so my image rotate only one time.
There is a way to get continous touch down event when I press my button?
Is there isn't such opportunity, how can I implement this continous rotation with the two buttons?
Sorry if I've said something wrong I'm new to iOS development.
There's a couple of ways you could do this - UIButtons have touchDown and touchUp events, so you could start a process on touchDown and end it on touchUpInside. This discussion might be useful.
Alternatively, rather than using UIbuttons you might want to try detecting a touchesBegan in a particular area (say on a UIImageView containing a button-lie image), then running the rotation animation until the touchesEnded event occurs?

How to catch touch events for CG content in UIView?

I have a UIView subclass that draws a curved line within it's frame (using Core Graphics). As expected, when you touch somewhere within the frame the view fires a touch event. But I only want the touch event to fire when the actual line is touched. How do I achieve that?
Thanks.
You'll have to setup some sort of collision detection. When you get a touch event in the frame, then call your "hit test" method. That method will simply check whether or not the touch point in the frame intersects with the curve.

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

How do I suppress animation during AutoRotation

I'm making an app where one of the objects needs to appear not to move or rotate during AutoRotation, but everything else needs to rotate and be repositioned. The way I did this is by manually rotating the object, and moving it into the same position, relative to the device, that it had prior to rotation. The problem is that it looks funny, appearing to rotate into the same position it had before.
If I suppress the animation effects during rotation, it would appear that the object never moved, and everything else just snapped into place, which is what I want. I haven't been able to find anything in the documentation that tells me how to do this though. How do I do this?
When it comes to UIViewController rotation there are two ways you can set up so you get a chance to rotate and move your own views.
In the one-step process, in your UIViewController-derived class provide an implementation of willAnimateRotationToInterfaceOrientation. It gets called and you can kick off your object rotation so while the system is rotating everything else your object is getting counter-rotated so it looks like it's staying put. You'll want to calculate how much to counter-rotate and in which direction based on current interface orientation vs. new orientation.
The other way is to get notified to do custom rotation in two steps. For example, in the first half you can shrink the object down, move it, and rotate it part way then in the second half finish the rotation as you scale back up to normal size. It's a pretty clever way to make the rotation animation look smoother to the eye.
For the two-step process, you need to define two methods. willAnimateFirstHalfOfRotationToInterfaceOrientation gets called for the first half of the rotation (i.e. up to 45 degrees for a 90 degree rotation and at 90 degrees for an upside down flip). Once past that point the second half is called via willAnimateSecondHalfOfRotationFromInterfaceOrientation.
If your object has a 1:1 aspect ratio (i.e square or round) and in the middle of the view then the one-step process will probably work fine. But if it's a non-square object and has to move position (for example if it's at position 40, 60 in portrait but moves to 20, 100 in landscape) and maybe even needs a bit of scaling to look better then you may want to try the two-step process and see if it looks smoother.
If your object is inside its own individual UIView then it's pretty easy to schedule the rotations through UIView animations. Just create a transform through CGAffineTransformMakeRotation, then inside a pair of UIView beginAnimations/commitAnimations blocks set the transform property of the view to this value. You can tweak the timing through setAnimationDuration.
EDIT: Based on the comments, I'm adding some code to show how you could attach the view to the top-level window instead of to the view controller. Your object would then reside in this view instead of the one managed by controller (which is getting rotated). You still need to over-ride the UIViewController rotate methods, but instead of rotating an object under control of the view controller you would trigger a counter-rotation in the object on the top-level.
To add a view to the top-level window:
YourAppDelegate* windowDelegate = ((YourAppDelegate*) [UIApplication sharedApplication].delegate);
[windowDelegate.window addSubview:yourView];
Keep a reference to yourView somewhere you can get to, then in the UIViewController's willAnimateRotationToInterfaceOrientation counter-rotate yourView, i.e. calculate how much to rotate the view in reverse to where you're going--if the phone is turning 90-degrees clockwise, you'll want to rotate the view back 90 degrees counter-clockwise, etc. Then use UIView animations on yourView.
If you don't want rotation animations, overload -shouldAutorotateToInterfaceOrientation: in your UIViewController and return NO. You can then observe UIDeviceOrientationDidChangeNotification to receive manual orientation change notifications.
This may work:
Listen for willRotateToInterfaceOrientation
[UIView setAnimationsEnabled:NO];
Listen for UIDeviceOrientationDidChangeNotification
[UIView setAnimationsEnabled:YES];
Untested, but I know that does work for some cases.