Question

Here is my situation: I have 3 UIImageViews. Two of them will act as reactors (the ones that the third one would be dragged to). The third one, like mentioned, will be draggable to one of the two UIImageViews like mentioned before.

I am currently using the touchesBegan, touchesMoved, and touchesEnded to accomplish this, but there is one problem.

After the draggable UIImageView has been dragged to one of the two UIImageViews, I want the draggable image view to snap back slowly (animation) to the original position (bottom center).

How could I accomplish this? Thanks in advance!

Was it helpful?

Solution

I tried out in a miniproject to do dragging-snapping using the more convenient UIPanGestureRecognizer. Hope it could solve your problem, comment if you need more info (you can download the GitHub project from https://github.com/codedad/SO_Drag_n_Snap_iOS ).

My ViewController.h:

@interface ViewController : UIViewController <UIGestureRecognizerDelegate> {
    CGPoint firstPos;
}

@property IBOutlet UIImageView *spot1;
@property IBOutlet UIImageView *spot2;
@property IBOutlet UIImageView *bkgr;
@property IBOutlet UIImageView *dragimg;

- (float) distanceSquared:(CGPoint) p1 p2:(CGPoint) p2;
- (IBAction)pan:(UIPanGestureRecognizer *)gesture;

My ViewController.m:

- (float) distanceSquared:(CGPoint) p1 p2:(CGPoint) p2 {
    float dx = (p1.x-p2.x);
    float dy = (p1.y-p2.y);
    return dx*dx+dy*dy;
}

void sort(int*a,int n,int*ndx) {
    int*b,*c,t;
    int*bi,*ci,ti;
    for(b=a+n,bi=ndx+n ; --b>a;) {
        --bi;
        for(c=b,ci=bi;--c>=a;) {
            --ci;
            if(*c>*b)t=*b,*b=*c,*c=t,ti=*bi,*bi=*ci,*ci=ti;
        }
    }
}

- (IBAction)pan:(UIPanGestureRecognizer *)gesture {
    CGPoint translatedPoint = [gesture translationInView:self.view];

    if ([gesture state] == UIGestureRecognizerStateBegan) {
        firstPos = [[gesture view] center];
    }

    translatedPoint = CGPointMake(firstPos.x+translatedPoint.x, firstPos.y+translatedPoint.y);
    [[gesture view] setCenter:translatedPoint];

    if ([gesture state] == UIGestureRecognizerStateEnded) {
        CGPoint snapPos;
        int distances[3];
        distances[0] = [self distanceSquared:dragimg.center p2:spot1.center];
        distances[1] = [self distanceSquared:dragimg.center p2:spot2.center];
        distances[2] = [self distanceSquared:dragimg.center p2:bkgr.center];
        int distances_ndx[3] = {0,1,2};
        sort(distances, 3, distances_ndx);

        switch (distances_ndx[0]) {
            case 0:
                snapPos = spot1.center;
                break;
            case 1:
                snapPos = spot2.center;
                break;
            default:
                snapPos = bkgr.center;
                break;
        }
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:0.2];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
        [UIView setAnimationDelegate:self];
        dragimg.center = snapPos;
        [UIView commitAnimations];
    }
}

my ViewController.xib:

I included 4 UIImageViews. 3 of them are static (spot1,2 and the "home" spot background halftone circle), plus the draggable yellow circle inside the "home" spot. I also added a pan gesture recognizer. Then I set the outlets:

  • uiimageviews are connected to spot1, spot2, bkgr and dragimg
  • pan gesture's delegate connected to the view, action connected to "pan" method
  • dragimg's gestureRecognizer then connected to the Pan Gesture Recognizer (added to the viewcontroller by dragging before)

enter image description here

  • you can add more spots if you extend the distance calculations and modify the sorting properly

OTHER TIPS

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{


UITouch *touch = [[event allTouches]anyObject];
if([touch view] == First_imageview)
{
}

UITouch *touch1 = [[event allTouches]anyObject];
if([touch1 view] == 2_imageview)
{
}

UITouch *touch2 = [[event allTouches]anyObject];
if([touch2 view] == 3_imageview)
{
}

}





    - (void) touchesMoved:(NSSet *)touches withEvent: (UIEvent *)event
 {

    UITouch *touch = [[event allTouches]anyObject];
    if([touch view] == First_imageview)
    {
    }

    UITouch *touch1 = [[event allTouches]anyObject];
    if([touch1 view] == 2_imageview)
    {
    }

    UITouch *touch2 = [[event allTouches]anyObject];
    if([touch2 view] == 3_imageview)
    {
    }
  }

Use this two method and drag your three imageview simply. i hope this code useful for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top