Search code examples
iosuiviewuibuttoncustom-controlsuicontrol

iOS 7 - how to drag the snapshot of the button or UIView instead of button itself


Right now I am able to drag a UIButton from one position to another using this code. Right now I am dragging the whole button itself. What I really want is to drag a snapshot of button with an alpha of 0.5 sort of effect. So the original button should stay at its place. I know iOS 7 onwards we have new methods like snapshotViewAfterScreenUpdates:YES, but my method uses UIControl. How should I go about changing mine to use that snapshot?

Another idea I had was to create a second button on top of current one and set alpha to .5 on that. And use that for drag and drop? But if I do this, then my button under this one won't be clickable :(

One more question, how would I detect that the user has stopped dragging so I can execute my function afterwards? I tried putting a call to my function in the "dragged45" method but that calls my function like a hundred times as the button is moving. I only want to call my function once the button has passed a certain point in the screen.

Here's my code so far:

created an action from the button with event and touch drag inside options:

- (IBAction)dragged45:(id)sender forEvent:(UIEvent *)event;

moving the button is done this way:

- (IBAction)dragged45:(id)sender forEvent:(UIEvent *)event {
 UIControl *control = sender;

 UITouch *t = [[event allTouches] anyObject];
 CGPoint pPrev = [t previousLocationInView:control];
 CGPoint p = [t locationInView:control];

 CGPoint center = control.center;
 center.x += p.x - pPrev.x;
 center.y += p.y - pPrev.y;
 control.center = center;
 NSLog(@"45 dragged!"); 
}

Edit: I was able to implement a check for if my button has passed a certain "line" in the view, then stop dragging.

Still curious about the snapshot part. And also is there a way to have a animation for if the button passes a line on the screen as well as if the user stops dragging before reaching the line?:

  • (IBAction)dragged45:(id)sender forEvent:(UIEvent *)event { NSLog(@"45 dragged!");

    UIControl *control = sender; if (control.center.y<150.0) { NSLog(@"Line passed!"); } else { UITouch *t = [[event allTouches] anyObject]; CGPoint pPrev = [t previousLocationInView:control]; CGPoint p = [t locationInView:control];

    CGPoint center = control.center;
    center.x += p.x - pPrev.x;
    center.y += p.y - pPrev.y;
    control.center = center;
    NSLog(@"After dragging button's x %f",center.x);
    NSLog(@"After dragging button's y %f",center.y);
    

    } }


Solution

  • UIButton is a UIControl, which is a UIView, so you can use the function like this.

    UIView *buttonCopy = [button snapshotViewAfterScreenUpdates:NO];
    

    Then add a UIPanGestureRecognizer to buttonCopy, when its state is UIGestureRecognizerStateEnded, you know user stopped dragging the view.