UIVIew 动画 - 缩放 +翻译

发布于 2024-09-15 00:07:10 字数 465 浏览 4 评论 0原文

我有一个视图,我想通过动画对其进行缩放并翻译到新位置。我尝试用以下代码来实现它:

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

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

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

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

谢谢

I have a view which I want to be scaled and translated to a new location by animating it. I tried to achieve it with the following code:

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

The effect of this code is, the view first changes its content's size to the finalRect and then translates it to the new location. i.e. The scaling part is never animated. The view is just transformed to the new size and then translated.

This issue is already discussed in several other threads but none of them draw a conclusion. A solution does exist though, to use a timer and set the frame each time in the timer callback, but it has a performance drawback.

What is the most appropriate solution to this problem, also, why in first case this problem occur?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

地狱即天堂 2024-09-22 00:07:10

设置框架既不缩放也不平移。您要么使用了错误的术语,要么使用了错误的工具来完成这项工作。当您希望影响 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屏幕。同样,这些需要包装在动画块中。

Setting the frame does neither a scale nor a translation. You are either using the wrong terminology or you are using the wrong tool for the job. Scale and translate are both done using Core Graphics Affine transforms when you're looking to affect the UIView (as opposed to the layer which use Core Animation transforms).

To scale a view use

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

To translate, use

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

To animate these, wrap them in an animation block. If you want to transform the view with both of these, then you need to concatenate them.

If you are not wanting scale and translation (transforms) at all, then what you mean is you want to change the view's bounds and position. These are changed with calls to

[view setBounds:newRect];
[view setCenter:newCenter];

Where newRect and newCenter are a CGRect and CGPoint respectively that represent the new position on the screen. Again, these need wrapped in an animation block.

原来分手还会想你 2024-09-22 00:07:10

这是一个块动画的示例:

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) { }
];

Here is an example with block animation:

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) { }
];
你是暖光i 2024-09-22 00:07:10

尝试这个解决方案:

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

Try this solution :

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

this operation is not commutative. The order is the opposite of the order when using convenience functions for applying one transform to another.

And you can use this operation to : for example (remove the Scale) :

    v2.transform =
    CGAffineTransformConcat(CGAffineTransformInvert(s), v2.transform);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文