pathを使ったアニメーションを試してみました。
作ったのは読み込み中などに動くアニメーションのようなもの。
ちょっとgifはかくかくしてますが、実際は滑らかに上からぐるぐると延々と回ります。
大雑把な作り方として
- 背景として円を描写
func backViewImage() -> UIImage {
var size = CGSize(width: self.view.bounds.width, height: self.view.bounds.height)
UIGraphicsBeginImageContext(size)
var context = UIGraphicsGetCurrentContext()
CGContextSaveGState(context)
var cyclePath : CGMutablePathRef = CGPathCreateMutable()
var cyclePath2 : CGMutablePathRef = CGPathCreateMutable()
var x : CGFloat = self.view.frame.size.width/2
var y : CGFloat = self.view.frame.size.height/2
var radius : CGFloat = 100.0
CGContextSetFillColorWithColor(context, UIColor.whiteColor().CGColor)
CGPathAddArc(cyclePath, nil, x, y, radius, CGFloat(0), CGFloat(M_PI*2), false)
CGContextSetLineWidth(context, 20);
CGContextSetStrokeColorWithColor(context, UIColor.grayColor().CGColor)
CGContextAddPath(context, cyclePath)
CGContextDrawPath(context, kCGPathStroke)
var image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
CGContextRestoreGState(context)
return image
}
作ったイメージをCALayerに追加するなりします。
- 動かす図を描写
/*
* 描画領域より大きい円を描いてその一部を描写する
*/
func cycleImage() -> UIImage {
var size : CGSize = CGSizeMake(20, 20)
var radius : CGFloat = 100
UIGraphicsBeginImageContext(size)
var context = UIGraphicsGetCurrentContext()
var path : CGMutablePathRef = CGPathCreateMutable()
CGPathAddArc(path, nil, size.width/2, radius+size.height/2, radius, CGFloat(M_PI), CGFloat(M_PI*2), false)
CGContextAddPath(context, path)
CGContextSetLineWidth(context, 20);
CGContextSetStrokeColorWithColor(context, UIColor.darkGrayColor().CGColor)
CGContextDrawPath(context, kCGPathStroke)
var image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
作った円を回る図を作り、それをUIImageViewにセットします。
作る図は背景の円の一部を切り取った形にしたい為、描画域の外に円の中心を求めて描いた円の-10〜10度あたりを切り取るような感じで描きます。
このテクニックは以下を参考
Core Graphics Tutorial: Arcs and Paths
以前は日本語のページもあったのですが、何故か無くなっています。分かりやすく色んなテクニックを教えてくれるいいサイトなんですが・・・。
- 作った図をパスで動かす
func animationPath(){
//パスでイメージを動かす
var animation = CAKeyframeAnimation(keyPath: "position")
animation.fillMode = kCAFillModeForwards
animation.removedOnCompletion = false
animation.duration = 10.0
animation.repeatCount = Float.infinity
var x : CGFloat = self.view.frame.size.width/2
var y : CGFloat = self.view.frame.size.height/2
var radius : CGFloat = 100.0
var cyclePath : CGMutablePathRef = CGPathCreateMutable()
CGPathAddArc(cyclePath, nil, x, y, radius, CGFloat(M_PI*(3/2)), CGFloat(-M_PI/2), false)
animation.path = cyclePath
imageView?.layer.addAnimation(animation, forKey: nil)
//イメージ自体を回転させる
var animation2 : CABasicAnimation = CABasicAnimation(keyPath: "transform")
animation2.delegate = self
animation2.fromValue = NSNumber(double: 0)
animation2.toValue = NSNumber(double: M_PI*2)
animation2.valueFunction = CAValueFunction(name: kCAValueFunctionRotateZ)
animation2.duration = 10
animation2.removedOnCompletion = false
animation2.fillMode = kCAFillModeForwards
animation2.repeatCount = Float.infinity
imageView?.layer.addAnimation(animation2, forKey: nil)
}
作った図を動かすパスを作成。そのパスを図をセットしたUIImageViewのレイヤーに追加。
さらに今回は動かす図をパスの動く時間に合わせて回転するようにします。これを追加しないとひっくり返ったお椀型の図が単に回る形になってしますので。