简体   繁体   中英

Reset UIView's frame with a pan gesture without hardcoding start values

I have a UIPanGestureRecognizer that is attached to a UIView. What I am trying to do is essentially drag and drop into a bucket. If the user lets go of the UIView and it's not in the bucket, I want it to animate back to its original start location. My selector that gets called for my UIPanGestureRecognizer is:

- (void)handleDragDescriptionView:(UIPanGestureRecognizer *)gestureRecognizer {
    UIView *panViewPiece = [gestureRecognizer view];
    CGRect originalFrame = CGRectMake(946, 20, 58, 30);

    CGPoint translation = [gestureRecognizer translationInView:panViewPiece];
    if (gestureRecognizer.state == UIGestureRecognizerStateBegan || gestureRecognizer.state == UIGestureRecognizerStateChanged) {
        panViewPiece.center = CGPointMake(panViewPiece.center.x + translation.x, panViewPiece.center.y + translation.y);

        [gestureRecognizer setTranslation:CGPointZero inView:panViewPiece.superview];
    }
    else if (gestureRecognizer.state == UIGestureRecognizerStateCancelled) {
        [UIView animateWithDuration:0.25 animations:^{
            self.dragDescriptionView.frame = originalFrame;
        }];
    }
    else {
        [UIView animateWithDuration:0.25 animations:^{
            self.dragDescriptionView.frame = originalFrame;
        }];
    }

}

I was wondering if I could do this without the originalFrame at the top of the method. I originally had

CGRect originalFrame = _dragDescriptionView.frame; 

instead of the hardcoding, but it doesn't snap back. Probably because I'm updating that value as I am dragging. I don't particularly like hardcoding values, but I wasn't sure if there was a way around this. Thanks!

You really only need to track the view's original center. Make originalCenter an instance variable and only set it when the gesture begins:

@implementation MyViewController {
    CGPoint _originalCenter;
}

- (void)handleDragDescriptionView:(UIPanGestureRecognizer *)gestureRecognizer {
    UIView *panViewPiece = [gestureRecognizer view];

    switch (gestureRecognizer.state) {
        case UIGestureRecognizerStateBegan:
            _originalCenter = panViewPiece.center;
            break;

        case UIGestureRecognizerStateChanged: {
            CGPoint translation = [gestureRecognizer translationInView:panViewPiece.superview];
            panViewPiece.center = CGPointMake(panViewPiece.center.x + translation.x, panViewPiece.center.y + translation.y);
            [gestureRecognizer setTranslation:CGPointZero inView:panViewPiece.superview];
            break;
        }

        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateCancelled: {
            [UIView animateWithDuration:0.25 animations:^{
                panViewPiece.center = _originalCenter;
            }];
            break;
        }

        default:
            break;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM