使用平移手势平滑地更改动画约束

Posted

技术标签:

【中文标题】使用平移手势平滑地更改动画约束【英文标题】:Animate constraint change smoothly with pan gesture 【发布时间】:2018-04-02 07:34:58 【问题描述】:

如何在 iOS 中通过平移手势平滑地动画约束变化?

我正在尝试开发一个屏幕,其中视图位于屏幕底部。我已经在该视图中添加了平移手势。在拖动该视图时,我想更改该视图的顶部约束。平移手势只允许在垂直和向下方向。我为拖动视图添加了一些限制。它工作但并不顺利。如何使用平移手势平滑地动画约束变化?这是我的代码。

 - (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)];
        ];
    

这是示例图片, 我的屏幕是这样的,但是在我的屏幕上,有一个地图视图而不是日历视图

【问题讨论】:

你应该让你的问题更清楚。怎么不流畅?我什至不知道firstTopminimumTop 是什么。如果你能给它一个 gif 或者调试 repo 是最好的,那就更好了。您提供的信息越多,您获得正确答案的速度就越快。 你到底有什么问题?你能制作一个问题的视频吗?我有一个使用平移识别器github.com/K-Be/ViewMovingTest 翻译视图的示例,并且在将转换应用于视图之前没有滞后。 【参考方案1】:

要在用户触摸屏幕时移动视图,您可以使用translationInView: 属性。您可以将set a translation 更改为当前约束的值并获取新值(在UIGestureRecognizerStateBegan 的处理程序中)并在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];
   

如果您需要在用户将拇指放在屏幕上向上或向下移动时移动视图,您可以使用速度。比如可以实现减速效果。

【讨论】:

我添加了带有预测和不带预测的垂直移动示例。 github.com/K-Be/ViewMovingTest,目标是 VerticalMoving。【参考方案2】:

如果你想让它动画流畅,尝试在动画块内调用layoutIfNeeded,如下所示:

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

【讨论】:

【参考方案3】:

我认为最初的问题是询问如何流畅地执行此动画。但是,如果地图视图约束链接到拖动视图约束,由于自动布局约束和布局 MKMapView 之间的多项式关系,计算将非常密集,因此可能会有延迟。如果 UI/UX 设计允许,我建议断开地图约束与拖动视图约束。

【讨论】:

以上是关于使用平移手势平滑地更改动画约束的主要内容,如果未能解决你的问题,请参考以下文章

快速平移手势移动约束

使用 Swift 动画约束更改(第二项)?

高度约束动画“跳跃”

使用平移的 UIImageView 移动不完全平滑

在横向调整和放置旋转视图:更新约束或平移/更改框架?

使用 setNeedsLayout 动画约束更改