2013-07-29 5 views
5

私はスピードメーターアプリを作っており、矢印が正しい方法で動作したいと思っています.1秒で0〜200kmを起動すると、バーを回りたいのですが、回転角度を十分大きく設定すると、それは、下から、短い道を行く。
どのようにすれば、短い経路ではなくほぼ完全な円にすることができますか?ここCGAffineTransformを使用してUIViewを回転する - 完全なパスにして短くする方法を教えてください。

私は回転のために使用する(ささいな)コードである:

[UIView animateWithDuration:0.3 animations:^(){ 

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

    }]; 

私は小さなチャンクでそれを回転させることができる図形、時には例えば、(ゼロから最大値まで迅速にそれを回転させるために必要とされるかもしれませんスピードについての読書がなく、すでに高速で取得しているので、ほとんどの画面を矢印で回転させる必要があります)。

アニメーションをキューに入れて1つずつ適用するにはどうすればよいですか?

答えて

3

私はもう一度同様の問題を抱えていました。私は180度しか動かす必要はありませんでしたが、時にはそれを時計回りに、時には反時計回りにする必要がありましたが、私はいつもその2つの間で前後に反転していました。

あなたはCALayerのとCAKeyframeAnimationsを使用する必要があり、ここでは私のために働いていたコードは次のとおりです。

-(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"]; 
} 
4

私は以下に含まれているしばらくこの小さなためのヘルパー関数を作りました。基本的に、UIKitは無用ですが、QuartzCoreフレームワークをインポートして、@Paul Cezanneが指摘したようにCAKeyframeAnimationを使用するか、CABasicAnimationを使用しなければなりません。

使い方は非常に簡単です。回転させたい画像ビュー、ラジアン単位の回転、アニメーションの長さと画像ビューが正しくアニメーション化されるように、下記のメソッドを呼び出します。実際にここに指定された方向があるため、常に「長い道のり」をとるでしょう。

アニメーションに正の値を渡すと、時計回りに回転してから自然に負の値が反時計回りに回転します。

[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"]; 
} 
1

SWIFT 3

私は正確に同じ問題を抱えていた、ここに私の解決策は、それが他の誰かを助け場合です。

リファレンスポインタを含む層:

@IBOutlet weak var pointerImageView: UIImageView! 

は最後のポインタ位置を追跡するための変数を定義します。

private var meterPointerRadians: CGFloat = 0 

はパーセンテージを使ってメーターの値を設定する関数を作成します。例:50%の速度

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) 

} 

ポインタの最後の位置に応じて、ポインタを時計回りまたは反時計回りに回転します。

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) 

} 
関連する問題