简体   繁体   中英

Animate constraint change smoothly with pan gesture

How to animate constraint change smoothly with pan gesture in iOS?

I am trying to develop a screen, where a view is at bottom of the screen. And I've added pan gesture to that view. On dragging that view I want change top constraint of that view. Pan gesture is only allowed in vertical and downward direction. I have added some limit for dragging the view. It working but not smoothly. How to animate constraint change smoothly with pan gesture? Here is my code.

 - (void)handleGesture:(UIPanGestureRecognizer *)sender
{
    CGPoint velocity = [sender velocityInView:_locationContainer];

    [sender setTranslation:CGPointMake(0, 0) inView:self.view];

    if (fabs(velocity.y) > fabs(velocity.x)) {

        NSLog(@"velocity y %f ",velocity.y * 0.13);

        if(velocity.y < 0 && (self.locationDetailsTop.constant > minimumTop) )
        {
            NSLog(@"gesture moving Up");
            self.locationDetailsTop.constant = self.locationDetailsTop.constant - fabs(velocity.y * 0.1);
        }
        else if (self.locationDetailsTop.constant < firstTop)
        {
            NSLog(@"gesture moving Bottom");

            self.locationDetailsTop.constant = self.locationDetailsTop.constant + fabs(velocity.y * 0.1);
        }

        [self.view layoutIfNeeded];
        [UIView animateWithDuration:0.1 animations:^{
            [self.mapView setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.locationContainer.frame.origin.y)];
        }];
    }
}

This is sample image, My screen is of the same kind like this, But on my screen, there is a map view instead of the calender view

在此处输入图片说明

To move view while user is touching a screen, you can use translationInView: property. You can set a translation to current constraint's value and get new value (in a handler of UIGestureRecognizerStateBegan ) and change a constraint's constant in a handler of UIGestureRecognizerStateChanged :

- (void)padRecognizerStateChanged:(UIPanGestureRecognizer*)sender
{
   if(sender.state == UIGestureRecognizerStateBegan)
   {
      [sender setTranslation:CGPointMake(0.0, [self getConstraintValue]) inView: _locationContainer]; 
   }
   else if (sender.state == UIGestureRecognizerStateChanged)
   {
      [self setConstraintValue: [sender translationInView:_locationContainer].y];
      [self.view setNeedsLayout];
   }
}

You can use velocity if you need to move view when a user raised his thumb over the screen for upward or downward movement. For example, you can implement deceleration effect.

If you want it to animate smoothly, try calling layoutIfNeeded inside the animation block like so:

[UIView animateWithDuration:0.1 animations:^{
    [self.view layoutIfNeeded];
    [self.mapView setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.locationContainer.frame.origin.y)];
}];

I think the original question was asking how to perform this animation smoothly. However, if the map view constraints are linked to the dragged view constraints, due to the polynomial relationship between autolayout constraints and laying out the MKMapView the computation will be quite intense and therefore there will likely be lag. I suggest disconnecting the map constraints from the dragged view constraints if the UI/UX design allows.

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