iOS - How to drag element during animation - iphone

i need to drag an element during an animation. The element fall from the top of the screen and i need the user can drag it wherever he want, even during animation
Thanks

You can use the touchesBegan method to detect when the user touches the element.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if (touch != nil && (touch.view == elementView))
//do your stuff
}
Then set the element's position to the touch location, and remove the animation.
elementView.center = [touch locationInView:self.view];
[elementView.layer removeAllAnimations];
This should work. Then you can use the similar touchesMoved method to update the position during the drag.

Since you're using the UIView block based animations, try using:
animateWithDuration:delay:options:animations:completion:
with the UIViewAnimationOptionAllowUserInteraction option.

Related

touchesMoved detection doesn't work properly

in my application I'm using touchesMoved method to detect swipe left/right.
when the user swipe to left and right continuously,image animation updates automatically.
I was able to detect swipe action but sometimes when I start to swipe left and right continuously,screen doesn't detect the touchmoved event.
in the swipe area I have placed one hidden button and few ImageViews for animations.
I want to know why it happens.please help me.
thank you.
code:
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesMoved:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint newLocation = [touch locationInView:self.view];
CGPoint oldLocation = [touch previousLocationInView:self.view];
if(newLocation.x-oldLocation.x>0){
swipe_direction = 1;
//NSLog(#"left");
}
else{
swipe_direction = 2;
//NSLog(#"right");
}
if(swipe_direction == 1){
//animate images
}
else if(swipe_direction == 2){
//animate images
}
}
touchesMoved Only detects on the empty part of the View. Therefore, it will not detect over the objects you used.
Place a SwipeGestureRecognizer over the view and use it from there.
Have you considered using a SwipeGestureRecognizer instead of the touchesMoved?
Check the Documentation

How to get effective Bounds of a subview in its parent view's co-ordinate system

In my app, I allow the user to annotate a photo by adding arrows (custom ArrowView). There can be many arrows added, with various zoom & rotation.
I am trying implement selecting of arrow by touch. Currently, I am iterating & using
CGRectContainsPoint(arrowView.frame, touchPoint)
to decide which arrow to select based on a touch gesture.
But, this does not work well when some of the arrows are big & rotated to 45 degrees (since the frame becomes big).
Question:
I would like to use bounds of the arrow translated to parent co-ordinates instead of frame. How can I get this when scaling & rotation is applied?
Alternatively, is there a better method to solve this selection problem?
This code find the arrow under touchPoint:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
UIView *arrow = [self.view hitTest:touchPoint withEvent:event];
}

iPhone - ignoring the second touch on an area

I have a view that the users are allowed to finger paint. The code is working perfectly if the area is touched with one finger. For example: I touch it with one finger and move the finger. Then, a line is drawn as I move the first finger. If I touch with a second finger the same view, the line that was being drawn by the first finger stops.
I would like to ignore any touch beyond the first, i.e., to track the first touch but ignore all others to the same view.
I am using touchesBegan/moved/ended.
I have used this to detect the touches
UITouch *touch = [[event allTouches] anyObject];
lastPoint = [touch locationInView:myView];
I have also tried this
lastPoint = [[touches anyObject] locationInView:myView];
but nothing changed.
How do I do that - track the first touch and ignore any subsequent touch to a view?
thanks.
NOTE: the view is NOT adjusted to detect multiple touches.
A given touch will maintain the same memory address as long as it is in contact with the screen. This means you can save the address as an instance variable and ignore any events from other objects. However, do not retain the touch. If you do, a different address will be used and your code won't work.
Example:
Add currentTouch to your interface:
#interface MyView : UIView {
UITouch *currentTouch;
...
}
...
#end
Modify touchesBegan: to ignore the touch if one is already being tracked:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if(currentTouch) return;
currentTouch = [touches anyObject];
...
}
Modify touchesMoved: to use currentTouch instead of getting a touch from the set:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if(!currentTouch) return;
CGPoint currentPoint = [currentTouch locationInView:myView];
...
}
Modify touchesEnded: and touchesCancelled: to clear currentTouch, but only if currentTouch has ended or been cancelled.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if(currentTouch && currentTouch.phase == UITouchPhaseEnded) {
...
currentTouch = nil;
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
if(currentTouch && currentTouch.phase == UITouchPhaseCancelled) {
...
currentTouch = nil;
}
}
yourView.multipleTouchEnabled = NO;
From the reference documents on UIView
multipleTouchEnabled
A Boolean value that indicates whether
the receiver handles multitouch
events.
#property(nonatomic, getter=isMultipleTouchEnabled) BOOL
multipleTouchEnabled Discussion
When set to YES, the receiver receives
all touches associated with a
multitouch sequence. When set to NO,
the receiver receives only the first
touch event in a multitouch sequence.
The default value of this property is
NO.
Other views in the same window can
still receive touch events when this
property is NO. If you want this view
to handle multitouch events
exclusively, set the values of both
this property and the exclusiveTouch
property to YES.

how to limit the position of a UIImageView inside a boundary range?

I got an Icon of UIImageView named IconView. I want to make sure when I touch and move this Icon, its position only change inside the boundary of another UIImageView named backgroundView.
I thought after I add the IconView as the subview of backgroundView, the boundary is automatically set. But it seems to be wrong.
[backgroundView addSubview:IconView];
after this, I can still move the Icon to the outside of backgroundView.
how can I set the limitation? thanks.
You try like this,
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:self.view];
if(CGRectContainsPoint(urBoundryBackgroundImage.frame, location)) {
//do your moving stuff
}
}

Handling touches on Iphone

Im having a little problem on handling touches in my apps.
I set my touchesBegan like this:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *currentTouch = [[event allTouches] anyObject];
touchPoint = [currentTouch locationInView:self.view];
if (CGRectContainsPoint(image1.frame, touchPoint)) {
image1IsTouched = YES;
}
}
Then i set my touch move like this:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *currentTouch = [[event allTouches] anyObject];
currentPoint = [currentTouch locationInView:currentTouch.view];
if(image1IsTouched == YES) {
image1.center = CGPointMake(currentPoint.x,currentPoint.y);
.....
}
}
Now i tried my app on actual unit and thats where i notice my problem. While im touching the image1 with 1 finger the app is doing ok and its checking for collision everytime i drag my finger. The problem occurs when i touch the screen with another finger while touching/dragging the image. The image im currently touching will jump to the other finger. I've tried [myView setMultipleTouchEnable:NO]; & using NSArray on touches and comparing the [touches count] with the touch but its not working. Can someone show me how to set a uiimageview to act on single touch only. Thanks.
First, you should use UITouch *currentTouch = [touches anyObject]; to get the current touch.
Second, you should check that touches.count == 1 to make sure there's only one finger on the screen, and ignore touch input if there's more than one, unless you wanted to support multitouch.