Tib*_*abo 9 cocoa-touch core-animation core-graphics objective-c ios
我想以圆形方式围绕任意点旋转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];
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*ist 10
anchorPoint使用关键帧动画实际上是一个锚点的变化是非常过分的.
锚点是应用所有变换的点,默认锚点是中心.通过将锚点移动到(0,0),您可以改为使图层从最底部的角落旋转.通过将锚点设置为x或y超出范围0.0 - 1.0的位置,可以使图层围绕位于其边界之外的点旋转.
有关详细信息,请阅读" 核心动画编程指南"中有关" 图层几何和变换"的部分.它详细介绍了图像,以帮助您理解.
使用位置,边界和锚点计算图层的框架(也是视图的框架).更改anchorPoint将更改视图在屏幕上显示的位置.您可以通过在更改定位点后重新设置框架来对此进行计数(这将为您设置位置).否则,您可以将位置设置为您自己旋转的点.的文档(与上文)也提到了这一点.
应更新您称为"transportPoint"的点,以计算标签的旋转点和左下角之间的差异除以宽度和高度.
// Pseudocode for the correct anchor point
transportPoint = ( (rotationX - labelMinX)/labelWidth,
(rotationX - labelMinY)/labelHeight )
Run Code Online (Sandbox Code Playgroud)
我还将旋转点作为您方法的参数.完整更新的代码如下:
#define DEGREES_TO_RADIANS(angle) (angle/180.0*M_PI)
- (void)rotateText:(UILabel *)label
aroundPoint:(CGPoint)rotationPoint
duration:(NSTimeInterval)duration
degrees:(CGFloat)degrees {
/* Setup the animation */
[UILabel beginAnimations:nil context:NULL];
[UILabel setAnimationDuration:duration];
// The anchor point is expressed in the unit coordinate
// system ((0,0) to (1,1)) of the label. Therefore the
// x and y difference must be divided by the width and
// height of the label (divide x difference by width and
// y difference by height).
CGPoint transportPoint = CGPointMake((rotationPoint.x - CGRectGetMinX(label.frame))/CGRectGetWidth(label.bounds),
(rotationPoint.y - CGRectGetMinY(label.frame))/CGRectGetHeight(label.bounds));
[label.layer setAnchorPoint:transportPoint];
[label.layer setPosition:rotationPoint]; // change the position here to keep the frame
[label.layer setTransform:CATransform3DMakeRotation(DEGREES_TO_RADIANS(degrees), 0, 0, 1)];
/* Commit the changes */
[UILabel commitAnimations];
}
Run Code Online (Sandbox Code Playgroud)
我决定发布我的解决方案作为答案.它工作正常接受它没有旧解决方案的曲线动画(UIViewAnimationCurveEaseOut),但我可以解决这个问题.
#define DEGREES_TO_RADIANS(angle) (angle / 180.0 * M_PI)
- (void)rotateText:(UILabel *)label duration:(NSTimeInterval)duration degrees:(CGFloat)degrees {
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddArc(path,nil, 160, 236, 100, DEGREES_TO_RADIANS(0), DEGREES_TO_RADIANS(degrees), YES);
CAKeyframeAnimation *theAnimation;
// animation object for the key path
theAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
theAnimation.path=path;
CGPathRelease(path);
// set the animation properties
theAnimation.duration=duration;
theAnimation.removedOnCompletion = NO;
theAnimation.autoreverses = NO;
theAnimation.rotationMode = kCAAnimationRotateAutoReverse;
theAnimation.fillMode = kCAFillModeForwards;
[label.layer addAnimation:theAnimation forKey:@"position"];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9164 次 |
| 最近记录: |