extension NSView { /** Shake the view. - Note: It will do nothing if the user has enabled the “Reduce motion” accessibility preference. */ func shake( duration: TimeInterval = 0.3, direction: NSUserInterfaceLayoutOrientation, moveAmount: Double = 5 ) { wantsLayer = true guard !NSWorkspace.shared.accessibilityDisplayShouldReduceMotion else { return } let translation = direction == .horizontal ? "x" : "y" let animation = CAKeyframeAnimation(keyPath: "transform.translation.\(translation)") animation.timingFunction = .easeInOut animation.duration = duration animation.values = [ -moveAmount, moveAmount, -(moveAmount / 2), moveAmount / 2, 0 ] layer?.add(animation, forKey: nil) } }