├── ressources ├── .DS_Store ├── logo.gif ├── record1.gif ├── record2.gif └── record3.gif ├── .gitignore ├── LICENSE ├── README.md └── source └── Anim.swift /ressources/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remirobert/Anim/HEAD/ressources/.DS_Store -------------------------------------------------------------------------------- /ressources/logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remirobert/Anim/HEAD/ressources/logo.gif -------------------------------------------------------------------------------- /ressources/record1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remirobert/Anim/HEAD/ressources/record1.gif -------------------------------------------------------------------------------- /ressources/record2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remirobert/Anim/HEAD/ressources/record2.gif -------------------------------------------------------------------------------- /ressources/record3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remirobert/Anim/HEAD/ressources/record3.gif -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | # Pods/ 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 rémi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

Anim

4 |

5 | 6 | 7 | Anim allows you to use animations very easily. You can use it in your UIKit application for make smooth animations, using Swift. 8 | 9 | 10 |

Features

11 | 12 | - Position (CGPoint) 13 | - Bounce effect 14 | - Resize (CGSize) 15 | - Rotation 16 | - Rotation X 17 | - Rotation Y 18 | - Rotation Z 19 | - Fade 20 | - Border raduis 21 | - Move circle 22 | - Animations sequence 23 | - Repeat animations 24 | - Block completion 25 | 26 |

How to use it

27 | 28 | You can use Anim with all Layers (UIButton, UItableViewCell, UItextField, UIView, ...). 29 | Anim provides a extension for CALayer, for use animation: 30 | 31 | ```Swift 32 | let animation = Animation.movePosition(CGPointMake(30, 30), delay: 1.5) 33 | self.myView.layer.runAnimation(animation) 34 | ``` 35 |
36 | 37 | You can use the block completion for link animation 38 | 39 | ```Swift 40 | let resizeAnimation = Animation.resize(CGSizeMake(30, 30), delay: 1.5) 41 | let bounceAnimation = Animation.bounce(30, delay: 0.1) 42 | 43 | self.myView.layer.runAnimation(resizeAnimation, blockCompletion: { () -> () in 44 | self.myView.layer.runAnimation(bounceAnimation) 45 | }) 46 | ``` 47 |
48 | 49 | You can also use sequence of animations. All animations in a sequence will be executed one after the other. 50 | 51 | ```Swift 52 | let sequenceAnimation = Animation.sequenceAnimations([Animation.resize(CGSizeMake(30, 30), delay: 1.5), 53 | Animation.bounce(30, delay: 0.1)]) 54 | 55 | self.myView.layer.runAnimation(sequenceAnimation) 56 | ``` 57 | 58 |
59 | 60 | Now there is the repeat animation method. For infinite or count animation. 61 | 62 | ```Swift 63 | let move = Animation.sequenceAnimations([Animation.movePosition(CGPointMake(10, 10), delay: 1.5), 64 | Animation.movePosition(CGPointMake(30, 30), delay: 1.5)]) 65 | let bounce = Animation.bounce(30, delay: 0.1) 66 | 67 | let repeatBouceForEver = Animation.repeatAnimations(Repeat.Infinity, animationParam: bounce) 68 | let repeatMove = Animation.repeatAnimations(Repeat.Count(10), animationParam: move) 69 | 70 | self.myView.layer.runAnimation(repeatBouceForEver) 71 | self.myView.layer.runAnimation(repeatMove) 72 | ``` 73 | 74 |
75 | 76 | For remove all current animation: 77 | 78 | ```Swift 79 | self.myView.layer.removeAllAnimations() 80 | ``` 81 | 82 |

Example

83 | 84 | Here are some example of use: 85 | 86 |

87 | 88 |

89 | 90 | 91 | ```Swift 92 | let animationStart = Animation.sequenceAnimations([Animation.resizeFrame(CGSizeMake(300, 300), delay: 2), Animation.rotationX(-0.85, delay: 2)]) 93 | 94 | 95 | o.layer.runAnimation(animationStart, blockCompletion: { () -> () in 96 | self.l.layer.runAnimation(Animation.movePosition(CGPointMake(100, 100), delay: 2)) 97 | self.l.layer.runAnimation(Animation.resizeFrame(CGSizeMake(100, 100), delay: 2), blockCompletion: { () -> () in 98 | 99 | self.l2.layer.runAnimation(Animation.movePosition(CGPointMake(110, 110), delay: 2)) 100 | self.l2.layer.runAnimation(Animation.resizeFrame(CGSizeMake(80, 80), delay: 2), blockCompletion: { () -> () in 101 | 102 | self.l3.layer.runAnimation(Animation.movePosition(CGPointMake(120, 120), delay: 2)) 103 | self.l3.layer.runAnimation(Animation.resizeFrame(CGSizeMake(60, 60), delay: 2), blockCompletion: { () -> () in 104 | 105 | o.layer.runAnimation(Animation.rotationX(0.85, delay: 2), blockCompletion: { () -> () in 106 | }) 107 | }) 108 | }) 109 | }) 110 | }) 111 | 112 | ``` 113 |
114 | 115 |

116 | 117 |

118 | 119 | ```Swift 120 | let a = Animation.repeatAnimations(Repeat.Count(3), animationParam: Animation.moveCircle(CGRectMake(0, 100, 200, 200), delay: 1)) 121 | let a2 = Animation.repeatAnimations(Repeat.Count(3), animationParam: Animation.moveCircle(CGRectMake(0, 100, 200, 200), delay: 1.5)) 122 | let a3 = Animation.repeatAnimations(Repeat.Count(3), animationParam: Animation.moveCircle(CGRectMake(0, 100, 200, 200), delay: 2)) 123 | 124 | l.layer.runAnimation(a) 125 | l2.layer.runAnimation(a2) 126 | l3.layer.runAnimation(a3) 127 | ``` 128 | 129 |
130 | 131 |

132 | 133 |

134 | 135 | ```Swift 136 | self.myImageView.layer.runAnimation(Animation.rotationY(Float(M_PI) * 4, delay: 2), blockCompletion: { () -> () in 137 | self.myImageView.layer.runAnimation(Animation.bounce(60, delay: 0.1)) 138 | self.myImageView.image = UIImage(named: "otherImage") 139 | }) 140 | ``` 141 | 142 |

Author

143 | Rémi ROBERT, remirobert33530@gmail.com 144 | 145 |

Licence

146 | Anim is available under the MIT license. See the LICENSE file for more info. 147 | 148 | 149 | -------------------------------------------------------------------------------- /source/Anim.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Animation.swift 3 | // Animation 4 | // 5 | // Created by Remi Robert on 08/10/14. 6 | // Copyright (c) 2014 remirobert. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum Repeat { 12 | case Count(Int) 13 | case Infinity 14 | } 15 | 16 | enum AnimationType { 17 | case Bounce(Float) 18 | case Position(CGPoint) 19 | case Resize(CGSize) 20 | case Rotation(Float) 21 | case RotationY(Float) 22 | case RotationX(Float) 23 | case RotationZ(Float) 24 | case Fade(Float) 25 | case BorderRaduis(Float) 26 | case Sequence(([Animation])) 27 | case Repeat((Int, Animation)) 28 | case MoveCircle(CGRect) 29 | case None 30 | } 31 | 32 | class Animation: NSObject { 33 | private var type: AnimationType = .None 34 | private var delay: NSTimeInterval = 0.5 35 | private var blockCompletion: (() -> ())? 36 | private var countAnimation: Int = 0 37 | private var animationsList: [Animation]? = nil 38 | 39 | //MARK: Bounce 40 | class func bounce(value: Float) -> Animation { 41 | let animation = Animation() 42 | 43 | animation.type = AnimationType.Bounce(value) 44 | return animation 45 | } 46 | 47 | class func bounce(value: Float, delay: NSTimeInterval) -> Animation { 48 | let animation = Animation() 49 | 50 | animation.delay = delay 51 | animation.type = AnimationType.Bounce(value) 52 | return animation 53 | } 54 | 55 | //MARK: Move Position 56 | class func movePosition(position: CGPoint) -> Animation { 57 | let animation = Animation() 58 | 59 | animation.type = AnimationType.Position(position) 60 | return animation 61 | } 62 | 63 | class func movePosition(position: CGPoint, delay: NSTimeInterval) -> Animation { 64 | let animation = Animation() 65 | 66 | animation.delay = delay 67 | animation.type = AnimationType.Position(position) 68 | return animation 69 | } 70 | 71 | //MARK: Resize Frame 72 | class func resizeFrame(resize: CGSize) -> Animation { 73 | let animation = Animation() 74 | 75 | animation.type = AnimationType.Resize(resize) 76 | return animation 77 | } 78 | 79 | class func resizeFrame(resize: CGSize, delay: NSTimeInterval) -> Animation { 80 | let animation = Animation() 81 | 82 | animation.delay = delay 83 | animation.type = AnimationType.Resize(resize) 84 | return animation 85 | } 86 | 87 | //MARK: Rotation Frame 88 | class func rotation(angle: Float) -> Animation { 89 | let animation = Animation() 90 | 91 | animation.type = AnimationType.Rotation(angle) 92 | return animation 93 | } 94 | 95 | class func rotation(angle: Float, delay: NSTimeInterval) -> Animation { 96 | let animation = Animation() 97 | 98 | animation.delay = delay 99 | animation.type = AnimationType.Rotation(angle) 100 | return animation 101 | } 102 | 103 | //MARK: 3D Rotation Y 104 | class func rotationY(rotation: Float) -> Animation { 105 | let animation = Animation() 106 | 107 | animation.type = AnimationType.RotationY(rotation) 108 | return animation 109 | } 110 | 111 | class func rotationY(rotation: Float, delay: NSTimeInterval) -> Animation { 112 | let animation = Animation() 113 | 114 | animation.delay = delay 115 | animation.type = AnimationType.RotationY(rotation) 116 | return animation 117 | } 118 | 119 | //MARK: 3D Rotation X 120 | class func rotationX(rotation: Float) -> Animation { 121 | let animation = Animation() 122 | 123 | animation.type = AnimationType.RotationX(rotation) 124 | return animation 125 | } 126 | 127 | class func rotationX(rotation: Float, delay: NSTimeInterval) -> Animation { 128 | let animation = Animation() 129 | 130 | animation.delay = delay 131 | animation.type = AnimationType.RotationX(rotation) 132 | return animation 133 | } 134 | 135 | //MARK: 3D Rotation Z 136 | class func rotationZ(rotation: Float) -> Animation { 137 | let animation = Animation() 138 | 139 | animation.type = AnimationType.RotationZ(rotation) 140 | return animation 141 | } 142 | 143 | class func rotationZ(rotation: Float, delay: NSTimeInterval) -> Animation { 144 | let animation = Animation() 145 | 146 | animation.delay = delay 147 | animation.type = AnimationType.RotationZ(rotation) 148 | return animation 149 | } 150 | 151 | //MARK: Fade 152 | class func fade(pourcent: Float) -> Animation { 153 | let animation = Animation() 154 | 155 | animation.type = AnimationType.Fade(pourcent) 156 | return animation 157 | } 158 | 159 | class func fade(pourcent: Float, delay: NSTimeInterval) -> Animation { 160 | let animation = Animation() 161 | 162 | animation.delay = delay 163 | animation.type = AnimationType.Fade(pourcent) 164 | return animation 165 | } 166 | 167 | //MARK: Border Raduis 168 | class func borderRaduis(angle: Float) -> Animation { 169 | let animation = Animation() 170 | 171 | animation.type = AnimationType.BorderRaduis(angle) 172 | return animation 173 | } 174 | 175 | class func borderRaduis(angle: Float, delay: NSTimeInterval) -> Animation { 176 | let animation = Animation() 177 | 178 | animation.delay = delay 179 | animation.type = AnimationType.BorderRaduis(angle) 180 | return animation 181 | } 182 | 183 | //MARK: sequence Animations 184 | class func sequenceAnimations(animations: [Animation]) -> Animation { 185 | let animation = Animation() 186 | 187 | animation.type = AnimationType.Sequence(animations) 188 | return animation 189 | } 190 | 191 | //MARK: repeat Animations 192 | class func repeatAnimations(count: Repeat, animationParam: Animation) -> Animation { 193 | let animation = Animation() 194 | 195 | switch count { 196 | case .Count(let value): 197 | animation.type = AnimationType.Repeat((value, animationParam)) 198 | case .Infinity: 199 | animation.type = AnimationType.Repeat((-1, animationParam)) 200 | } 201 | return animation 202 | } 203 | 204 | //MARK: Move arround circle 205 | class func moveCircle(frameCircle: CGRect) -> Animation { 206 | let animation = Animation() 207 | 208 | animation.type = AnimationType.MoveCircle(frameCircle) 209 | return animation 210 | } 211 | 212 | class func moveCircle(frameCircle: CGRect, delay: NSTimeInterval) -> Animation { 213 | let animation = Animation() 214 | 215 | animation.delay = delay 216 | animation.type = AnimationType.MoveCircle(frameCircle) 217 | return animation 218 | } 219 | 220 | private func createAnimation(pathAnimation: String, delay: NSTimeInterval) -> CABasicAnimation { 221 | let animation = CABasicAnimation(keyPath: pathAnimation) 222 | 223 | animation.fillMode = kCAFillModeForwards 224 | animation.removedOnCompletion = false 225 | animation.delegate = self 226 | animation.duration = delay 227 | animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) 228 | return animation 229 | } 230 | 231 | override func animationDidStop(anim: CAAnimation!, finished flag: Bool) { 232 | blockCompletion?() 233 | } 234 | 235 | private func runBounce(layer:CALayer, value:Float, blockCompletion: (() -> ())?) { 236 | if value <= 3 { 237 | if let block = blockCompletion { 238 | block() 239 | } 240 | return Void() 241 | } 242 | UIView.animateWithDuration(self.delay, animations: { () -> Void in 243 | layer.frame = CGRectMake(layer.frame.origin.x - CGFloat(value / 2), layer.frame.origin.y - CGFloat(value / 2), 244 | layer.frame.size.width + CGFloat(value), 245 | layer.frame.size.height + CGFloat(value)) 246 | }) { (Bool) -> Void in 247 | 248 | UIView.animateWithDuration(self.delay, animations: { () -> Void in 249 | layer.frame = CGRectMake(layer.frame.origin.x + CGFloat(value / 2), layer.frame.origin.y + CGFloat(value / 2), 250 | layer.frame.size.width - CGFloat(value), 251 | layer.frame.size.height - CGFloat(value)) 252 | }, completion: { (Bool) -> Void in 253 | self.runBounce(layer, value: value / 2, blockCompletion: blockCompletion) 254 | }) 255 | } 256 | } 257 | 258 | private func runMovePosition(layer: CALayer, position: CGPoint, blockCompletion: (() -> ())?) { 259 | UIView.animateWithDuration(self.delay, animations: { () -> Void in 260 | layer.frame = CGRectMake(position.x, position.y, layer.frame.size.width, layer.frame.size.height) 261 | }) { (Bool) -> Void in 262 | if let block = blockCompletion { 263 | block() 264 | } 265 | } 266 | } 267 | 268 | private func runResize(layer: CALayer, resize: CGSize, blockCompletion: (() -> ())?) { 269 | UIView.animateWithDuration(self.delay, animations: { () -> Void in 270 | layer.frame = CGRectMake(layer.frame.origin.x, layer.frame.origin.y, 271 | resize.width, resize.height) 272 | }) { (Bool) -> Void in 273 | if let block = blockCompletion { 274 | block() 275 | } 276 | } 277 | } 278 | 279 | private func runRotation(layer:CALayer, rotation: Float, blockCompletion: (() -> ())?) { 280 | let animation = createAnimation("transform.rotation", delay: self.delay) 281 | 282 | animation.fromValue = 0 283 | if let currentLayer: AnyObject = layer.presentationLayer() { 284 | animation.fromValue = Float(currentLayer.valueForKeyPath("transform.rotation") as NSNumber) 285 | } 286 | 287 | self.blockCompletion = blockCompletion 288 | animation.toValue = rotation + Float(animation.fromValue as NSNumber) 289 | layer.addAnimation(animation, forKey: "rotation") 290 | } 291 | 292 | private func runRotationY(layer: CALayer, y: Float, blockCompletion: (() -> ())?) { 293 | let animation = createAnimation("transform.rotation.y", delay: self.delay) 294 | var rotation = CATransform3DIdentity 295 | 296 | animation.fromValue = 0 297 | if let currentLayer: AnyObject = layer.presentationLayer() { 298 | animation.fromValue = Float(currentLayer.valueForKeyPath("transform.rotation.y") as NSNumber) 299 | } 300 | 301 | self.blockCompletion = blockCompletion 302 | rotation.m34 = 1.0 / 500.0 303 | animation.toValue = y + Float(animation.fromValue as NSNumber) 304 | layer.addAnimation(animation, forKey: "rotationY") 305 | layer.transform = rotation 306 | } 307 | 308 | private func runRotationX(layer: CALayer, x: Float, blockCompletion: (() -> ())?) { 309 | let animation = createAnimation("transform.rotation.x", delay: self.delay) 310 | var rotation = CATransform3DIdentity 311 | 312 | animation.fromValue = 0 313 | if let currentLayer: AnyObject = layer.presentationLayer() { 314 | animation.fromValue = Float(currentLayer.valueForKeyPath("transform.rotation.x") as NSNumber) 315 | } 316 | 317 | self.blockCompletion = blockCompletion 318 | rotation.m34 = 1.0 / 500.0 319 | animation.toValue = x + Float(animation.fromValue as NSNumber) 320 | layer.addAnimation(animation, forKey: "rotationX") 321 | layer.transform = rotation 322 | } 323 | 324 | private func runRotationZ(layer: CALayer, z: Float, blockCompletion: (() -> ())?) { 325 | let animation = createAnimation("transform.rotation.z", delay: self.delay) 326 | var rotation = CATransform3DIdentity 327 | 328 | animation.fromValue = 0 329 | if let currentLayer: AnyObject = layer.presentationLayer() { 330 | animation.fromValue = Float(currentLayer.valueForKeyPath("transform.rotation.z") as NSNumber) 331 | } 332 | 333 | self.blockCompletion = blockCompletion 334 | rotation.m34 = 1.0 / 500.0 335 | animation.toValue = z + Float(animation.fromValue as NSNumber) 336 | layer.addAnimation(animation, forKey: "rotationZ") 337 | layer.transform = rotation 338 | } 339 | 340 | private func runFade(layer: CALayer, pourcent: Float, blockCompletion: (() -> ())?) { 341 | let animation = createAnimation("opacity", delay: self.delay) 342 | 343 | self.blockCompletion = blockCompletion 344 | animation.toValue = pourcent 345 | layer.addAnimation(animation, forKey: "fade") 346 | } 347 | 348 | private func runBorderRaduis(layer: CALayer, angle: Float, blockCompletion: (() -> ())?) { 349 | let animation = createAnimation("cornerRadius", delay: self.delay) 350 | 351 | self.blockCompletion = blockCompletion 352 | animation.toValue = 15.0 353 | animation.fromValue = layer.cornerRadius 354 | layer.addAnimation(animation, forKey: "angleRaduis") 355 | } 356 | 357 | private func runMoveCircle(layer: CALayer, frameCircle: CGRect, blockCompletion: (() -> ())?) { 358 | let animation = CAKeyframeAnimation(keyPath: "position") 359 | self.blockCompletion = blockCompletion 360 | 361 | animation.path = CGPathCreateWithEllipseInRect(frameCircle, nil) 362 | animation.fillMode = kCAFillModeForwards 363 | animation.removedOnCompletion = false 364 | animation.delegate = self 365 | animation.duration = delay 366 | animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) 367 | 368 | animation.additive = true; 369 | animation.calculationMode = kCAAnimationPaced; 370 | animation.rotationMode = kCAAnimationRotateAuto; 371 | layer.addAnimation(animation, forKey: "moveCircle") 372 | } 373 | 374 | private func execAnimationSequence(layer:CALayer) { 375 | if self.countAnimation >= self.animationsList?.count { 376 | self.blockCompletion?() 377 | return Void() 378 | } 379 | 380 | let currentAnimation = self.animationsList?[self.countAnimation] 381 | 382 | currentAnimation?.runAnimation(layer, blockCompletion: { () -> () in 383 | self.countAnimation += 1 384 | self.execAnimationSequence(layer) 385 | }) 386 | } 387 | 388 | private func runSequenceAnimation(layer: CALayer, animations: [Animation], blockCompletion: (() -> ())?) { 389 | self.blockCompletion = blockCompletion 390 | self.countAnimation = 0 391 | self.animationsList = animations 392 | self.execAnimationSequence(layer) 393 | } 394 | 395 | 396 | private func runRepeatAnimation(layer: CALayer, count: Int, animation: Animation, blockCompletion: (() -> ())?) { 397 | if count == 0 { 398 | blockCompletion?() 399 | return Void() 400 | } 401 | animation.runAnimation(layer, blockCompletion: { () -> () in 402 | self.runRepeatAnimation(layer, count: count - 1, animation: animation, blockCompletion: blockCompletion) 403 | }) 404 | } 405 | 406 | private func runAnimation(layer: CALayer, blockCompletion: (() -> ())?) { 407 | switch self.type { 408 | case .Bounce(let value): 409 | self.runBounce(layer, value: value, blockCompletion: blockCompletion) 410 | case .Position(let value): 411 | self.runMovePosition(layer, position: value, blockCompletion: blockCompletion) 412 | case .Resize(let value): 413 | self.runResize(layer, resize: value, blockCompletion: blockCompletion) 414 | case .Rotation(let value): 415 | self.runRotation(layer, rotation: value, blockCompletion: blockCompletion) 416 | case .RotationY(let value): 417 | self.runRotationY(layer, y: value, blockCompletion: blockCompletion) 418 | case .RotationX(let value): 419 | self.runRotationX(layer, x: value, blockCompletion: blockCompletion) 420 | case .RotationZ(let value): 421 | self.runRotationZ(layer, z: value, blockCompletion: blockCompletion) 422 | case .Fade(let value): 423 | self.runFade(layer, pourcent: value, blockCompletion: blockCompletion) 424 | case .BorderRaduis(let value): 425 | self.runBorderRaduis(layer, angle: value, blockCompletion: blockCompletion) 426 | case .Sequence(let animations): 427 | self.runSequenceAnimation(layer, animations: animations, blockCompletion: blockCompletion) 428 | case .Repeat(let count, let animation): 429 | self.runRepeatAnimation(layer, count: count, animation: animation, blockCompletion: blockCompletion) 430 | case .MoveCircle(let value): 431 | self.runMoveCircle(layer, frameCircle: value, blockCompletion: blockCompletion) 432 | case .None: 433 | Void() 434 | } 435 | } 436 | } 437 | 438 | extension CALayer { 439 | 440 | func runAnimation(animation: Animation) { 441 | animation.runAnimation(self, blockCompletion: nil) 442 | } 443 | 444 | func runAnimation(animation: Animation, blockCompletion :(() -> ())) { 445 | animation.runAnimation(self, blockCompletion: blockCompletion) 446 | } 447 | } --------------------------------------------------------------------------------