如何使物体绕任意点旋转?
我想以圆形方式围绕任意点旋转 UILabel,而不是直线。这是我的代码。最后一个点是完美的,但它穿过初始点和结束点之间的一条直线。
- (void)rotateText:(UILabel *)label duration:(NSTimeInterval)duration degrees:(CGFloat)degrees {
/* Setup the animation */
[UILabel beginAnimations:nil context:NULL];
[UILabel setAnimationDuration:duration];
CGPoint rotationPoint = CGPointMake(160, 236);
CGPoint transportPoint = CGPointMake(rotationPoint.x - label.center.x, rotationPoint.y - label.center.y);
CGAffineTransform t1 = CGAffineTransformTranslate(label.transform, transportPoint.x, -transportPoint.y);
CGAffineTransform t2 = CGAffineTransformRotate(label.transform,DEGREES_TO_RADIANS(degrees));
CGAffineTransform t3 = CGAffineTransformTranslate(label.transform, -transportPoint.x, +transportPoint.y);
CGAffineTransform t4 = CGAffineTransformConcat(CGAffineTransformConcat(t1, t2), t3);
label.transform = t4;
/* Commit the changes */
[UILabel commitAnimations];
}
I want to rotate an UILabel around an arbitrary point in a circular manner, not a straight line. This is my code.The final point is perfect but it goes through a straight line between the initial and the end points.
- (void)rotateText:(UILabel *)label duration:(NSTimeInterval)duration degrees:(CGFloat)degrees {
/* Setup the animation */
[UILabel beginAnimations:nil context:NULL];
[UILabel setAnimationDuration:duration];
CGPoint rotationPoint = CGPointMake(160, 236);
CGPoint transportPoint = CGPointMake(rotationPoint.x - label.center.x, rotationPoint.y - label.center.y);
CGAffineTransform t1 = CGAffineTransformTranslate(label.transform, transportPoint.x, -transportPoint.y);
CGAffineTransform t2 = CGAffineTransformRotate(label.transform,DEGREES_TO_RADIANS(degrees));
CGAffineTransform t3 = CGAffineTransformTranslate(label.transform, -transportPoint.x, +transportPoint.y);
CGAffineTransform t4 = CGAffineTransformConcat(CGAffineTransformConcat(t1, t2), t3);
label.transform = t4;
/* Commit the changes */
[UILabel commitAnimations];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您应该设置自己的
anchorPoint
使用关键帧动画来实现真正的锚点更改是非常过分的。
锚点是应用所有变换的点,默认锚点是中心。通过将锚点移动到 (0,0),您可以使图层从最底角旋转。通过将锚点设置为 x 或 y 超出 0.0 - 1.0 范围的位置,您可以让图层绕其边界之外的点旋转。
请阅读图层几何和变换部分核心动画编程指南了解更多信息。 它通过图像详细介绍了这一点,以帮助您理解。
编辑:要记住的一件事
图层的框架(也是视图的框架)是使用位置、边界和锚点计算的观点。更改锚点将更改您的视图在屏幕上的显示位置。您可以通过在更改锚点后重新设置框架来解决此问题(这将为您设置位置)。否则,您可以将位置设置为您自己旋转的点。 文档(链接到上面)也提到了这一点。
应用于您的代码
您称为“transportPoint”的点应更新,以计算旋转点与标签左下角之间的差值除以宽度和高度。
我还将旋转点作为您方法的参数。完整更新的代码如下:
You should set your own
anchorPoint
Its very much overkill to use a keyframe animation for what really is a change of the anchor point.
The anchor point is the point where all transforms are applied from, the default anchor point is the center. By moving the anchor point to (0,0) you can instead make the layer rotate from the bottom most corner. By setting the anchor point to something where x or y is outside the range 0.0 - 1.0 you can have the layer rotate around a point that lies outside of its bounds.
Please read the section about Layer Geometry and Transforms in the Core Animation Programming Guide for more information. It goes through this in detail with images to help you understand.
EDIT: One thing to remember
The frame of your layer (which is also the frame of your view) is calculated using the position, bounds and anchor point. Changing the anchorPoint will change where your view appears on screen. You can counter this by re-setting the frame after changing the anchor point (this will set the position for you). Otherwise you can set the position to the point you are rotating to yourself. The documentation (linked to above) also mentions this.
Applied to you code
The point you called "transportPoint" should be updated to calculate the difference between the rotation point and the lower left corner of the label divided by the width and height.
I also made the rotation point an argument to your method. The full updated code is below:
我决定发布我的解决方案作为答案。它工作得很好,接受它没有旧解决方案的曲线动画(UIViewAnimationCurveEaseOut),但我可以解决这个问题。
I decided to post my solution as an answer. It works fine accept it doesn't have the old solutions's curve animations (UIViewAnimationCurveEaseOut), but I can sort that out.
CAKeyframeAnimation
是适合这项工作的工具。大多数 UIKit 动画都在起点和终点之间。不考虑中间点。 CAKeyframeAnimation 允许您定义这些中间点以提供非线性动画。您必须为动画提供适当的贝塞尔曲线路径。您应该查看此示例
以及 Apple 文档中提供的示例,了解其工作原理。CAKeyframeAnimation
is the right tool for this job. Most UIKit animations are between start and end points. The middle points are not considered. CAKeyframeAnimation allows you to define those middle points to provide a non-linear animation. You will have to provide the appropriate bezier path for your animation. You should look atthis example
and the one's provided in the Apple documentation to see how it works.平移、绕中心旋转、向后平移。
translate, rotate around center, translate back.