Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save warren-gavin/e1ed07ba4160d7f002848bd4602f9923 to your computer and use it in GitHub Desktop.
Save warren-gavin/e1ed07ba4160d7f002848bd4602f9923 to your computer and use it in GitHub Desktop.
var animationDuration: CFTimeInterval { get }
protocol Shakeable {
var horizontalShake: CGFloat { get }
var verticalShake: CGFloat { get }
var animationDuration: CFTimeInterval { get }
var repeatCount: Float { get }
func shake()
}
struct Defaults {
static let horizontalShake: CGFloat = 4.0
static let verticalShake: CGFloat = 0.0
static let duration: CFTimeInterval = 0.05
static let repeatCount: Float = 5
}
extension Shakeable {
var horizontalShake: CGFloat {
return Defaults.horizontalShake
}
var verticalShake: CGFloat {
return Defaults.verticalShake
}
var animationDuration: CFTimeInterval {
return Defaults.duration
}
var repeatCount: Float {
return Defaults.repeatCount
}
}
extension Shakeable where Self: UIView {
func shake() {
let position = "position"
let animation = CABasicAnimation(keyPath: position)
animation.duration = animationDuration
animation.repeatCount = repeatCount
animation.autoreverses = true
animation.fromValue = NSValue(cgPoint: CGPoint(x: center.x - horizontalShake,
y: center.y - verticalShake))
animation.toValue = NSValue(cgPoint: CGPoint(x: center.x + horizontalShake,
y: center.y + verticalShake))
layer.add(animation, forKey: position)
}
}
class ImageView: UIImageView, Shakeable {
@IBInspectable var horizontalShake: CGFloat = Defaults.horizontalShake
@IBInspectable var verticalShake: CGFloat = Defaults.verticalShake
}
class Button: UIButton, Shakeable {
@IBInspectable var horizontalShake: CGFloat = Defaults.horizontalShake
@IBInspectable var verticalShake: CGFloat = Defaults.verticalShake
}
protocol Shakeable {
var horizontalShake: CGFloat { get }
var verticalShake: CGFloat { get }
var duration: CFTimeInterval { get }
var repeatCount: Float { get }
func shake()
}
protocol ShakeablesContainer {
var shakeables: [Shakeable] { get }
func shake()
}
extension ShakeablesContainer {
func shake() {
shakeables.forEach { $0.shake() }
}
}
class ViewController: UIViewController, ShakeablesContainer {
@IBOutlet weak var imageView: ImageView!
@IBOutlet weak var button: Button!
@IBAction func shake(_ sender: Button) {
shake()
}
var shakeables: [Shakeable] {
return [imageView, button].flatMap {
$0 as? Shakeable
}
}
}
@abhishekbedi1432
Copy link

abhishekbedi1432 commented Aug 15, 2016

Since the shake direction is limited to horizontal and vertical in this case, what say if we use enum for the shake direction

enum ShakeDirection {
case horizontal
case vertical
}
protocol Shakeable {
    var shakeDirection: ShakeDirection = .horizontal
    var animationDuration: CFTimeInterval { get }
    var repeatCount: Float { get }  
    func shake()
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment