拖动时为 UIView 设置动画

Posted

技术标签:

【中文标题】拖动时为 UIView 设置动画【英文标题】:Animate UIView while being dragged 【发布时间】:2012-05-31 10:33:31 【问题描述】:

我正在尝试为 UIView 在用户开始拖动时展开动画,并在用户停止拖动时为其折叠动画。在 ios5 中,这似乎可以工作,虽然并不完美 - 视图在展开时动画移动到当前手指位置(因此滞后),但在展开动画结束时工作正常。

在 iOS4 中,它只是被破坏了 - 视图以动画方式展开,但在动画完成之前根本不会用用户的手指移动。

我能做什么?

- (void)gestureRecognizerMoved:(id)sender

    [self.view bringSubviewToFront:[(UIPanGestureRecognizer*)sender view]];
    CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.view];
    NSLog(@"translated x %f y %f", translatedPoint.x, translatedPoint.y);

    if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan)
        
        firstX = [sender view].center.x;
        firstY = [sender view].center.y;

        NSLog(@"first x %f y %f", firstX, firstY);
    

    translatedPoint = CGPointMake([sender view].center.x, firstY+translatedPoint.y);
    [[sender view] setCenter:translatedPoint];

    if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan)
    
        [UIView animateWithDuration:0.8f animations:^(void)
         
             CGRect frame = [sender view].frame;
             frame.size.width += 200.0f;
             [sender view].frame = frame;
         ];
    

    if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded)
    
        [UIView animateWithDuration:0.8f animations:^(void)
         
             CGRect frame = [sender view].frame;
             frame.size.width -= 200.0f;
             [sender view].frame = frame;
         ];
    

编辑:使用 Core Graphics 仿射变换来调整视图大小(例如 CGAffineTransformMakeScale)而不是修改视图的框架摆脱了 iOS5 中的滞后,所以现在即使在动画期间它也会坚持用户的手指按压,而不是动画到新闻地点,完美!但是在 iOS4 中仍然遇到同样的问题。

【问题讨论】:

你试过 UIViewAnimationOptionAllowUserInteraction 作为动画选项吗? 这行得通,谢谢!如果是评论,有没有办法可以接受这个作为答案? 我把它作为答案发布了 【参考方案1】:

您可能应该在动画选项中包含UIViewAnimationOptionBeginFromCurrentState

编辑:

您应该使用UIViewAnimationOptionBeginFromCurrentState,因为您的手势可以在动画结束之前结束。

更改视图center 只是更改视图frame 的另一种方式。这两个属性更改相同的数据。如果您为 frame 大小设置动画,然后直接通过 center 更改帧(覆盖动画所做的),您将无法获得所需的内容。

我看到的最简单的解决方案是将您的视图放入透明容器中并更改容器的位置,同时视图仍然可以为其大小设置动画。

【讨论】:

试过了,没用。根据我的理解, UIViewAnimationOptionBeginFromCurrentState 将用于例如在动画已经被动画的视图时(所以它不会从它的实际位置开始第二个动画,但它是在第一个动画期间的插值位置)对吗?就我而言,我只做一个动画,同时手动移动帧中心。 抱歉,我没有注意到您直接更改了center。查看更新的答案。【参考方案2】:

尝试使用 UIViewAnimationOptionAllowUserInteraction 选项,它应该可以工作:)

【讨论】:

以上是关于拖动时为 UIView 设置动画的主要内容,如果未能解决你的问题,请参考以下文章

在目标 c 中移动 UIView 时为其设置动画

如何在像快门一样从上到下加载时为 UIView 设置动画?

UIView锚点->拖动->旋转变换导致闪烁

在为 `tableHeaderView` 设置动画时为 `UITableView` 标头设置动画

选择时为 UICollectionViewCell 大小设置动画

jQuery在单击对象时为对象设置动画,当单击主体时,再次设置动画