【问题标题】:UIVIew animation - Scaling + TranslatingUIVIew 动画 - 缩放 + 平移
【发布时间】:2011-03-31 09:13:47
【问题描述】:

我有一个视图,我想通过动画将其缩放并转换到新位置。我尝试使用以下代码来实现它:

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:kDurationForFullScreenAnimation];
[[self animatingView] setFrame:finalRect];
[UIView commitAnimations];

这段代码的效果是,视图首先将其内容的大小更改为finalRect,然后将其转换到新位置。即缩放部分从不动画。视图只是被转换为新的大小,然后被翻译。

这个问题已经在其他几个线程中讨论过,但没有一个得出结论。虽然确实存在一种解决方案,即使用计时器并在计时器回调中每次设置帧,但它存在性能缺陷。

什么是这个问题最合适的解决方案,还有,为什么在第一种情况下会出现这个问题?

谢谢

【问题讨论】:

    标签: cocoa-touch uikit uiview core-animation uiviewanimation


    【解决方案1】:

    设置框架既不缩放也不平移。您要么使用了错误的术语,要么使用了错误的工具来完成这项工作。当您希望影响 UIView(与使用 Core Animation 变换的层相反)时,缩放和平移都使用 Core Graphics 仿射变换完成。

    要缩放视图,请使用

    // 2x
    [rotationView setTransform:CGAffineTransformMakeScale(2.0, 2.0)];
    

    要翻译,请使用

    // Move origin by 100 on both axis
    [rotationView setTransform:CGAffineTransformMakeTranslation(100.0, 100.0)];
    

    要为这些设置动画,请将它们包装在一个动画块中。如果您想用这两种方式转换视图,则需要将它们连接起来。

    如果您根本不想要缩放和平移(变换),那么您的意思是您想要更改视图的边界和位置。这些会随着对

    的调用而改变
    [view setBounds:newRect];
    [view setCenter:newCenter];
    

    其中 newRectnewCenter 分别是一个 CGRectCGPoint 代表屏幕上的新位置。同样,这些需要包装在一个动画块中。

    【讨论】:

    • 问题是,如果我这样做,视图及其所有子视图的内容会立即采用 newRect。它们没有动画到新帧。就像说你有一个 imageView 作为动画视图的子视图,imageView 中的图像不会逐渐缩放。相反,图像首先被放大到 newRect,然后视图的边界缩放 + 平移。虽然更改中心在动画块中有效,但更改边界并没有按预期进行。
    【解决方案2】:

    下面是块动画的例子:

    CGPoint newCenter = CGPointMake(100.0,100.0);
    
    [UIView animateWithDuration: 1
                          delay: 0
                        options: (UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction)
                     animations:^{object.center = newCenter ; object.transform = CGAffineTransformScale(CGAffineTransformIdentity, 2.0, 2.0);}
                     completion:^(BOOL finished) { }
    ];
    

    【讨论】:

      【解决方案3】:

      试试这个解决方案:

        CGAffineTransform s =  CGAffineTransformMakeScale(0.5f,0.5f);
        CGAffineTransform t = CGAffineTransformMakeTranslation(100, 0);
        v2.transform = CGAffineTransformConcat(t,s); // not s,t
      

      此操作不可交换。该顺序与使用便捷函数将一个变换应用于另一个变换时的顺序相反。

      您可以使用此操作来:例如(删除比例):

          v2.transform =
          CGAffineTransformConcat(CGAffineTransformInvert(s), v2.transform);
      

      【讨论】:

      • 很好的答案。在我所有的搜索中,这个让我得到了我需要的东西,让这个动画像我需要的那样工作。在选择具有标签缩小和向左的文本字段时,我正在尝试复制动画。只是一个比例变换缩小了标签,但向下和向右。还需要翻译转换,但我找不到让两者都起作用的方法。 CGAffineTransformConcat 是关键。谢谢!
      猜你喜欢
      • 2011-11-29
      • 2012-07-08
      • 1970-01-01
      • 2017-05-30
      • 2015-03-30
      • 2013-12-17
      • 1970-01-01
      • 1970-01-01
      • 2011-07-04
      相关资源
      最近更新 更多