I have a circular UIBezierPath. I use the path to draw a circle on my view to create an outline of a 24 hr clock. I have a UIButton whose position depends on the current time. The button acts like an Hour hand. I want the users to be able to move the UIButton along the circular path. I call it "visit the future/past" feature. How do I restrict the buttons movement to the path I have?
Override touchesBegan: and touchesMoved: methods in your view
- (void)touchesBegan: (NSSet *)touches withEvent:(UIEvent *)event
{
if([[event touchesForView:button] count])
{
//User is trying to move the button set a variable to indicate this.
}
}
- (void)touchesMoved: (NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint *point = [[event anyObject] locationInView:self];
/*Compare x and y coordinates with the centre property of the button
If x or y are greater set center of button to next point in circle or previous
point if any of them are lesser.*/
}
Note that you will have to save all points in your circle in an array before attempting this or you will have to calculate the points on the circumference of the circle by knowing the radius.
The easiest way is in touchesMoved, you can check to ignore touch which is not in your circle view by using:
CGPoint point = [touch locationInView:circleView];
if (![circleView pointInside:point withEvent:event]) {
return;
}
Related
I have to do some "snap to grid" behaviour,
I have a dragging image "sprite", but I need to "snap" this sprite to a certain button if touches go on top of that button,
so how can i know if touchesEnded is on top of a certain button,
here my code, but i dont know when touches where ended on top of butotn
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touched = [[event allTouches] anyObject];
CGPoint location = [touched locationInView:touched.view];
CGRect recta = touched.view.frame;
if (CGRectIntersectsRect(recta, self.button_1.frame)) {
DLog(#"intersected");
}
}
So this is not happening,
can it be done?
or do i have to check the X and Y position of finishing touch against the button frame X and Y position by my self?
cheers
touched.view is the view on which the touch started. You want to find out if the location where the touch ended is on top of a specific button. You can do this by checking if the location of the touch relative to the button is within the button's bounds.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touched = [[event allTouches] anyObject];
CGPoint locationRelative = [touched locationInView:self.button_1];
if (CGRectContainsPoint(self.button_1.bounds, locationRelative)) {
DLog(#"on top of button_1");
}
}
You can use CGRectIntersectsRect, which returns YES, if the two rectangles your pass to it intersect.
I would like my sprite to move from one side of the screen to the other like this:
Before tapped:
http://imgur.com/wIFa3JL
And then after the screen has been tapped:
http://imgur.com/ZtWiE7b
Would it start with something like this:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
Thank you!
I am not quite sure if you want to get the position of your finger when you touch the screen and apply to the sprite's position or just to change the position of the sprite when you touch the screen.
If you want to get your finger's position inside touchesBegan and apply that position to the sprite:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches) {
CGPoint location = [touch locationInView:self];
spriteNode.position = location;
}
}
If you want to just change the sprite's position to the opposite side of the tree every time you touch:
First you need to keep track of which side your sprite is currently. Let's create a BOOL to hold that info:
BOOL isRightSide;
Then, at the beginning, if your sprite start at the right side of the tree, just assign TRUE to the boolean.
Finally, in the touch event:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (isRightSide) {
//Change to sprite's position to the LEFT side
} else {
//Change to sprite's position to the RIGHT side
}
isRightSide = !isRightSide;
}
I hope this helps =)
I am doing the View resize,move and rotate on single touch.
I am trying to find the touch moved direction like,
IF touch moved direction is Horizontal or Vertical then MOve the view.
If touch moved direction is diagonal then resize.
And if touch moved like rotate gesture then rotate the View.
I am able to identify the Horizontal or Vertical direction.
Please suggest me how i can identify the diagonal and rotation.
I guess for rotation, you can simply use this mehod -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event.
And for diagonal, you can compare coordinates of both the points.
For diagonal, you can take help from this post also.
Try This:
TDResizerView
both view rotation and move is available in this
in touch move function, you can identify the direction of move finger like this.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint current=[touch locationInView:self];
CGPoint last=[touch previousLocationInView:self];
if(current.x>last.x){
NSLog(#">>>>rigth");
}else{
NSLog(#">>>>left");
}
if(current.y>last.y){
NSLog(#">>>>up");
}else{
NSLog(#">>>>down");
}
}
I am developing a simple animation where an UIImageView moves along a UIBezierPath, now I want to provide user interation to the moving UIImageView so that user can guide the UIImageView by touching the UIImageView and drag the UIImageview around the screen.
Change the frame of the position of the image view in touchesMoved:withEvent:.
Edit: Some code
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
UITouch *touch = [[event allTouches] anyObject];
if ([touch.view isEqual: self.view] || touch.view == nil) {
return;
}
lastLocation = [touch locationInView: self.view];
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
UITouch *touch = [[event allTouches] anyObject];
if ([touch.view isEqual: self.view]) {
return;
}
CGPoint location = [touch locationInView: self.view];
CGFloat xDisplacement = location.x - lastLocation.x;
CGFloat yDisplacement = location.y - lastLocation.y;
CGRect frame = touch.view.frame;
frame.origin.x += xDisplacement;
frame.origin.y += yDisplacement;
touch.view.frame = frame;
lastLocation=location;
}
You should also implement touchesEnded:withEvent: and touchesCanceled:withEvent:.
So you want the user to be able to touch an image in the middle of a keyframe animation along a curved path, and drag it to a different location? What do you want to happen to the animation at that point?
You have multiple challenges.
First is detecting the touch on the object while a keyframe animation is "in flight".
To do that, you want to use the parent view's layer's presentation layer's hitTest method.
A layer's presentation layer represents the state of the layer at any given instant, including animations.
Once you detect touches on your view, you will need to get the image's current location from the presentation layer, stop the animation, and take over with a touchesMoved/touchesDragged based animation.
I wrote a demo application that shows how to detect touches on an object that's being animated along a path. That would be a good starting point.
Take a look here:
Core Animation demo including detecting touches on a view while an animation is "in flight".
Easiest way would be subclassing UIImageView.
For simple dragging take a look at the code here (code borrowed from user MHC):
UIView drag (image and text)
Since you want to drag along Bezier path you'll have to modify touchesMoved:
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *aTouch = [touches anyObject];
//here you have location of user's finger
CGPoint location = [aTouch locationInView:self.superview];
[UIView beginAnimations:#"Dragging A DraggableView" context:nil];
//commented code would simply move the view to that point
//self.frame = CGRectMake(location.x-offset.x,location.y-offset.y,self.frame.size.width, self.frame.size.height);
//you need some kind of a function
CGPoint calculatedPosition = [self calculatePositonForPoint: location];
self.frame = CGRectMake(calculatedPosition.x,calculatedPosition.y,self.frame.size.width, self.frame.size.height);
[UIView commitAnimations];
}
What exactly you would like to do in -(CGPoint) calculatePositionForPoint:(CGPoint)location
is up to you. You could for example calculate point in Bezier path that is the closest to location. For simple test you can do:
-(CGPoint) calculatePositionForPoint:(CGPoint)location {
return location;
}
Along the way you're gonna have to decide what happens if user wonders off to far from your
precalculated Bezier path.
I making an app which sets the sleep timer with a clock .Basically it is clock which has a single hand which user can move to set his sleep time .I tried to rotate the image with uitouch but it rotates from middle but i want it to rotate from the tip.Secondly i want that the image only rotates when user is touching the tip of the image but in my project the image is also rotating when use touches any part of the screen.Also i want to rotate the image in both directions but in my project it moves only clockwise due to this method
image.transform = CGAffineTransformRotate(image.transform, degreesToRadians(1));
Can anybody give me hints or solutions about how can it be done?
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
//
touch = [[event allTouches] anyObject];
touchLocation = [touch locationInView:touch.view];
NSLog(#"began");
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
// get touch event
[image.layer setAnchorPoint:CGPointMake(0.0,0.0)];
if ([touch view] == image) {
image.transform = CGAffineTransformRotate(image.transform, degreesToRadians(1));
//image.center = touchLocation;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(#"end");
}
In detail, you can custom a rotateView,then:
1: In the delegate method of "touchesBegan", get initialPoint of finger and initialAngle.
2: During "touchesMoved",get the newPoint of finger:
CGPoint newPoint = [[touches anyObject] locationInView:self];
[self pushTouchPoint:thePoint date:[NSDate date]];
double angleDif = [self angleForPoint:newPoint] - [self angleForPoint:initialPoint];
self.angle = initialAngle + angleDif;
[[imageView layer] setTransform:CATransform3DMakeRotation(angle, 0, 0, 1)];
3: At last, in "touchesEnded" you can calculate final AngularVelocity.
If anything being confused, for more detail, you can write back.
To rotate it the other way you just use:
image.transform = CGAffineTransformRotate(image.transform, degreesToRadians(1));
And to rotate form the tip you should use setAnchorPoint (like you used in your code, but i think you should do: [image setAnchorPoint]).
more on the subject: setAnchorPoint for UIImage?
I tried to rotate the image with uitouch but it rotates from middle but i want it to rotate from the tip
I dont know any way in SDK to rotate an element on its extreme end. If you want to have that effect take the clock handle image you have twice in length with half portion transparent. It is not a direct solution, but a workaround.
Also i want to rotate the image in both directions but in my project it moves only clockwise due to this method
As per iOS developer documentation, a positive angle value specifies counterclockwise rotation and a negative value specifies clockwise rotation.