2017-08-09 18 views
0

CABasicAnimationを使用して円を拡大縮小したいとします。私は以前、sinUIViewクラスのdrawRectメソッドを使用してアニメーションを描画するためのきれいで効果的な方法を設計しましたが、残念ながらdrawRectをアニメーション化したり、実行することはできません。UIView.animateメソッドでは、したがって、私はCABasicAnimationを使用して回避策を考え出す必要がありました。結果の種類の作品が、アニメーションは醜いですし、右に見えません。ここで私が何を意味するかの実例です:CABasicAnimationでサークル半径を適切にアニメーション化

enter image description here

反りが膨張・収縮の際に発生し、円が拡大しているとき、右側のくぼみや空洞があるように見えます。ここではそれをアニメーション化する責任クラスです:

struct PathConfig { 
    var arcCenter: CGPoint 
    var radius: CGFloat 
    let startAngle: CGFloat = 0.0 
    let endAngle: CGFloat = CGFloat(2 * M_PI) 
} 

class RGSStandbyIndicatorView: UIView { 

    // MARK: - Variables & Constants 

    /// The drawing layer. 
    var shapeLayer: CAShapeLayer! 

    // MARK: - Class Methods 

    /// Animation function. 
    func animate(period: CFTimeInterval) { 
     let p: PathConfig = PathConfig(arcCenter: CGPoint(x: frame.width/2, y: frame.height/2) , radius: 17.5) 
     let b: UIBezierPath = UIBezierPath(arcCenter: p.arcCenter, radius: p.radius, startAngle: p.startAngle, endAngle: p.endAngle, clockwise: true) 
     let a: CABasicAnimation = CABasicAnimation(keyPath: "path") 

     a.fromValue = shapeLayer.path 
     a.toValue = b.cgPath 
     a.autoreverses = true 
     a.duration = period 
     a.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) 
     a.repeatCount = HUGE 
     shapeLayer.add(a, forKey: "animateRadius") 
    } 

    /// Initializes and returns a CAShapeLayer with the given draw path and fill color. 
    private class func shapeLayerForPath(_ path: CGPath, with fillColor: CGColor) -> CAShapeLayer { 
     let shapeLayer: CAShapeLayer = CAShapeLayer() 
     shapeLayer.path = path 
     shapeLayer.fillColor = fillColor 
     return shapeLayer 
    } 

    /// Configures the UIView 
    private func setup() { 

     // Init config, path. 
     let cfg: PathConfig = PathConfig(arcCenter: CGPoint(x: frame.width/2, y: frame.height/2) , radius: 0.0) 
     let path: UIBezierPath = UIBezierPath(arcCenter: cfg.arcCenter, radius: cfg.radius, startAngle: cfg.startAngle, endAngle: cfg.endAngle, clockwise: true) 

     // Init CAShapeLayer 
     shapeLayer = RGSStandbyIndicatorView.shapeLayerForPath(path.cgPath, with: UIColor.white.cgColor) 

     layer.addSublayer(shapeLayer) 
    } 

    // MARK: Class Method Overrides 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     setup() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     setup() 
    } 

} 

私はそれが何のオーバーラップを有していないパスのいくつかのアーティファクトだったが、それは何も変更しませんでした期待して開始と終了の角度を調整しようとしました。私はこの問題を解決する方法がわかりませんし、チャドウィック・ウッドのanswerも同様の質問に基づいています。

+0

あなたがCGAffineTransform.scaleを使用して、ビューが角の半径で丸め作るドントなぜ助け? –

答えて

1

使用このUIViewのサブクラスを

class RadioAnimationView: UIView { 

    var animatableLayer : CAShapeLayer? 

    override func awakeFromNib() { 
     super.awakeFromNib() 
     self.layer.cornerRadius = self.bounds.height/2 

     self.animatableLayer = CAShapeLayer() 
     self.animatableLayer?.fillColor = self.backgroundColor?.cgColor 
     self.animatableLayer?.path = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.layer.cornerRadius).cgPath 
     self.animatableLayer?.frame = self.bounds 
     self.animatableLayer?.cornerRadius = self.bounds.height/2 
     self.animatableLayer?.masksToBounds = true 
     self.layer.addSublayer(self.animatableLayer!) 
     self.startAnimation() 
    } 


    func startAnimation() 
    { 
     let layerAnimation = CABasicAnimation(keyPath: "transform.scale") 
     layerAnimation.fromValue = 1 
     layerAnimation.toValue = 3 
     layerAnimation.isAdditive = false 
     layerAnimation.duration = CFTimeInterval(2) 
     layerAnimation.fillMode = kCAFillModeForwards 
     layerAnimation.isRemovedOnCompletion = true 
     layerAnimation.repeatCount = .infinity 
     layerAnimation.autoreverses = true 

     self.animatableLayer?.add(layerAnimation, forKey: "growingAnimation") 
    } 

} 

希望これはあなた

+0

ありがとう、これは私の現在の試みよりもはるかに優れています。それは私の問題を解決しました。私は正直なところ、CAAffineTransformについて何も知らなかった。私は最初の午後にいくつかのアニメーションを手に入れようとしていましたが、CABasicAnimationでトンネリングされました。 – Micrified

+0

@Owatchあなたはアプローチは有効ですが、ヘルパー関数を使用して、弧の半径を変更するすべての時間空間で適切なパスを取得する必要があります。より良いアプローチ、私はあなたを助けてうれしい、ハッピーコーディングと最高の点 –