首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >旋转UIView与CGAffineTransform -如何使它走满路径而不是短路径?

旋转UIView与CGAffineTransform -如何使它走满路径而不是短路径?
EN

Stack Overflow用户
提问于 2013-07-29 15:51:24
回答 3查看 2.1K关注 0票数 6

我正在制作一个速度计应用程序,我希望箭头的行为方式正确--如果我在一秒钟内从零发射到200公里,我希望它绕着吧台旋转,但是如果我把旋转角度设置得足够大,它就会从底部向短方向移动。

我如何使它几乎是一个圆圈,而不是通过短途?

下面是我用于旋转的(琐碎)代码:

代码语言:javascript
运行
复制
[UIView animateWithDuration:0.3 animations:^(){

        self.arrow.transform = CGAffineTransformRotate(CGAffineTransformIdentity, -4.4);

    }];

我想我可以把它旋转成小块,但有时它可能需要快速地从零旋转到最大(例如,如果我们没有速度读数,并且已经得到了高速,所以我们需要旋转屏幕的大部分箭头)。

作为一个附带的问题-我如何排队动画,以便我可以一个一个地应用?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-08-06 12:36:09

不久前我也有过类似的问题。我只需要去180度,但有时我需要顺时针方向,有时逆时针方向,但我总是在两者之间来回翻转,因此代码中的“旋转”属性。

您需要使用CALayer和CAKeyframeAnimations,下面是对我有用的代码:

代码语言:javascript
运行
复制
-(void) showHideSpinnerWithDuration:(float) duration;
{
    CALayer* layer = _spinner.layer;
    CAKeyframeAnimation* animation;
    animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];

    animation.duration = duration;
    animation.cumulative = YES;
    animation.repeatCount = 1;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;

    if (_rotated) {
        animation.values = [NSArray arrayWithObjects:
                            [NSNumber numberWithFloat:DegreesToRadians(180)],
                            [NSNumber numberWithFloat:DegreesToRadians(0)],
                            nil];
        self.rotated = NO;
    } else {
        animation.values = [NSArray arrayWithObjects:
                            [NSNumber numberWithFloat:DegreesToRadians(0)],
                            [NSNumber numberWithFloat:DegreesToRadians(180)],
                            nil];
        self.rotated = YES;
    }

    animation.keyTimes = [NSArray arrayWithObjects:
                          [NSNumber numberWithFloat:0.0],
                          [NSNumber numberWithFloat:duration], nil];

    animation.timingFunctions = [NSArray arrayWithObjects:
                                 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
                                 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], nil];

    [layer addAnimation:animation forKey:@"transform.rotation.z"];
}
票数 3
EN

Stack Overflow用户

发布于 2013-08-09 23:53:52

我为这个函数做了一个帮助函数,它包含在下面。基本上,UIKit对此毫无用处,您必须导入QuartzCore框架并使用@Paul指出的CAKeyframeAnimation,或者使用CABasicAnimation,我认为它可以很好地处理这个问题。

使用非常简单,只需调用下面详细的方法,传递您想要旋转的图像视图、以弧度表示的旋转,以及动画持续时间和图像视图将正确地动画。它总是要走“很长的路”,因为这里实际上有一个指定的方向。

如果你把正数传递给动画,它会顺时针旋转,然后,负值自然会引起逆时针旋转。

代码语言:javascript
运行
复制
[self rotateView:imageView rotationInRadians:M_PI duration:2.0];


- (void)rotateView:(UIImageView *)imageView rotationInRadians:(CGFloat)radians duration:(CFTimeInterval)duration
{
    CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];

    [rotationAnimation setToValue:[NSNumber numberWithFloat:radians]];
    [rotationAnimation setDuration:duration];
    [rotationAnimation setCumulative:YES];
    [rotationAnimation setFillMode:kCAFillModeForwards];
    [rotationAnimation setRemovedOnCompletion:NO];

    [imageView.layer addAnimation:rotationAnimation forKey:@"gaugeRotationAnimation"];
}
票数 4
EN

Stack Overflow用户

发布于 2017-05-18 22:39:10

SWIFT 3

我也遇到了同样的问题,这是我的解决方案,以防对其他人有帮助。

引用包含指针的层:

代码语言:javascript
运行
复制
@IBOutlet weak var pointerImageView: UIImageView!

定义一个变量来跟踪最后一个指针位置:

代码语言:javascript
运行
复制
private var meterPointerRadians: CGFloat = 0

创建一个使用百分比设置仪表值的函数。50%的速度

代码语言:javascript
运行
复制
func setMeter(dialPercentage: Double) {

    //define the start and end angles of your speed meter: Eg: from 90 to 180 (semi circle)
    let meterLowerRangeAngle: Double = 90.0 
    let meterUpperRangeAngle: Double = 180.0

    //calculate the angle of the pointer in radians
    let range = meterUpperRangeAngle - meterLowerRangeAngle
    let angle = (dialPercentage * range / 100) + meterLowerRangeAngle
    let radians: CGFloat = CGFloat(angle * .pi / 180)

    rotatePointer(imageView: self.pointerImageView, rotationInRadians: radians, duration: 1)

}

根据指针的最后位置,顺时针或逆时针旋转指针。

代码语言:javascript
运行
复制
func rotatePointer(imageView: UIImageView, rotationInRadians: CGFloat, duration: CFTimeInterval) {

    let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation.z")

    rotationAnimation.fromValue = meterPointerRadians
    rotationAnimation.toValue = rotationInRadians
    rotationAnimation.duration = duration
    rotationAnimation.isCumulative = true
    rotationAnimation.fillMode = kCAFillModeBoth
    rotationAnimation.isRemovedOnCompletion = false

    imageView.layer.add(rotationAnimation, forKey: "pointerRotationAnimation")
    meterPointerRadians = CGFloat(rotationInRadians)

}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17928521

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档