[解決済み] アニメーションによる円の描画
質問
円の描画をアニメーション化する方法を探しています。円を作成することはできましたが、まとめて描画してしまいます。
以下は、私の
CircleView
クラスです。
import UIKit
class CircleView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.clearColor()
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func drawRect(rect: CGRect) {
// Get the Graphics Context
var context = UIGraphicsGetCurrentContext();
// Set the circle outerline-width
CGContextSetLineWidth(context, 5.0);
// Set the circle outerline-colour
UIColor.redColor().set()
// Create Circle
CGContextAddArc(context, (frame.size.width)/2, frame.size.height/2, (frame.size.width - 10)/2, 0.0, CGFloat(M_PI * 2.0), 1)
// Draw
CGContextStrokePath(context);
}
}
そして、ビューコントローラーのビュー階層に追加する方法は以下の通りです。
func addCircleView() {
let diceRoll = CGFloat(Int(arc4random_uniform(7))*50)
var circleWidth = CGFloat(200)
var circleHeight = circleWidth
// Create a new CircleView
var circleView = CircleView(frame: CGRectMake(diceRoll, 0, circleWidth, circleHeight))
view.addSubview(circleView)
}
円の描画を1秒かけてアニメーションさせる方法はありますか?
例)アニメーションの途中で、この画像の青い線のような感じになります。
どのように解決するのですか?
最も簡単な方法は、コアアニメーションの力を使って作業のほとんどを代行させることです。これを行うには、円を描くコードを
drawRect
関数から
CAShapeLayer
. 次に
CABasicAnimation
をアニメーション化するために
CAShapeLayer
's
strokeEnd
からのプロパティ
0.0
から
1.0
.
strokeEnd
はこのマジックの大きな部分を占めています; docs から。
strokeStart プロパティと組み合わせて、このプロパティはストロークするパスの このプロパティは、ストロークするパスのサブ領域を定義します。このプロパティの値は このプロパティの値は、ストロークを終了するパスに沿った相対的なポイントを示し、strokeStartプロパティは開始ポイントを定義します。 strokeStart プロパティは開始点を定義する。0.0を指定すると の値はパスの始点を表し、1.0 の値はパスの終点を表す。 はパスの終点を表す。その間の値は、パスの長さに沿って直線的に解釈される。 パスの長さに沿って線形に解釈されます。
もし
strokeEnd
を
0.0
に設定すると、何も描画されません。もし、これを
1.0
に設定すると、完全な円が描かれる。もし、これを
0.5
とすれば、半円が描かれます。
では、手始めに
CAShapeLayer
の中に
CircleView
's
init
関数に追加し、そのレイヤーをビューの
sublayers
に追加します (また、必ず
drawRect
関数を削除してください)。
let circleLayer: CAShapeLayer!
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.clearColor()
// Use UIBezierPath as an easy way to create the CGPath for the layer.
// The path should be the entire circle.
let circlePath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0), radius: (frame.size.width - 10)/2, startAngle: 0.0, endAngle: CGFloat(Double.pi * 2.0), clockwise: true)
// Setup the CAShapeLayer with the path, colors, and line width
circleLayer = CAShapeLayer()
circleLayer.path = circlePath.CGPath
circleLayer.fillColor = UIColor.clearColor().CGColor
circleLayer.strokeColor = UIColor.redColor().CGColor
circleLayer.lineWidth = 5.0;
// Don't draw the circle initially
circleLayer.strokeEnd = 0.0
// Add the circleLayer to the view's layer's sublayers
layer.addSublayer(circleLayer)
}
注意
を設定しています。
circleLayer.strokeEnd = 0.0
を設定し、円がすぐに描画されないようにしています。
さて、円のアニメーションをトリガーするために呼び出すことができる関数を追加しましょう。
func animateCircle(duration: NSTimeInterval) {
// We want to animate the strokeEnd property of the circleLayer
let animation = CABasicAnimation(keyPath: #keyPath(CAShapeLayer.strokeEnd))
// Set the animation duration appropriately
animation.duration = duration
// Animate from 0 (no circle) to 1 (full circle)
animation.fromValue = 0
animation.toValue = 1
// Do a linear animation (i.e. the speed of the animation stays the same)
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
// Set the circleLayer's strokeEnd property to 1.0 now so that it's the
// right value when the animation ends.
circleLayer.strokeEnd = 1.0
// Do the actual animation
circleLayer.add(animation, forKey: "animateCircle")
}
そして、あとはあなたの
addCircleView
を追加したときにアニメーションを開始するようにします。
CircleView
をその
superview
:
func addCircleView() {
let diceRoll = CGFloat(Int(arc4random_uniform(7))*50)
var circleWidth = CGFloat(200)
var circleHeight = circleWidth
// Create a new CircleView
var circleView = CircleView(frame: CGRectMake(diceRoll, 0, circleWidth, circleHeight))
view.addSubview(circleView)
// Animate the drawing of the circle over the course of 1 second
circleView.animateCircle(1.0)
}
全部合わせるとこんな感じになるはずです。
注意 このように繰り返されるのではなく、アニメートした後、一周したままになります。
関連
-
[解決済み】円・矩形の衝突判定(交差判定)について)
-
[解決済み] SVGの円弧パスによる円形描画
-
[解決済み] Swiftで1つのビューコントローラの向きを縦向きのみに固定する方法
-
[解決済み] Protocol ... can only be used as generic constraint because it has Self or associated type requirements "とは、どういう意味ですか?
-
[解決済み] UIViewの定高制約をプログラムで更新するには?
-
[解決済み] Swiftスクリプトでターミナルコマンドを実行するには?(例:xcodebuild)
-
[解決済み] 非'@objc'メソッドは'@objc'プロトコルのオプション要件を満たしていない
-
[解決済み] Swiftで範囲を作成する方法は?
-
[解決済み] Swift: インデックスで文字列配列を置換する
-
[解決済み] Swift - サブクラスでオーバーライドする必要があるクラスメソッド
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Swift Error fatal error: Optional value のアンラップ中に予期せず nil を発見した。
-
swift 4.0でのdispatch_async,dispatch_afterの使用について
-
[解決済み] Swiftで1つのビューコントローラの向きを縦向きのみに固定する方法
-
[解決済み] Swiftダブルからストリング
-
[解決済み] Swift 3でカスタム通知を作成するには?
-
[解決済み] UIViewの定高制約をプログラムで更新するには?
-
[解決済み] Swiftで警告を消すには?
-
[解決済み] Swiftのリバースレンジ
-
[解決済み] ""内の二重引用符を印刷するには?
-
[解決済み] Swift - 複数条件でオブジェクトの配列を並べ替える