Hurry! Try our new Interactive Courses for FREE. 🥳   🚀
Not satisfied by the Answer? Still have doubts?
Ask Question

How do I detect when someone shakes an iPhone?

I want to react when somebody shakes the iPhone. I don't particularly care how they shake it, just that it was waved vigorously about for a split second. Does anyone know how to detect this?
motion-detection accelerometer ios

2 Answers

In 3.0, there's now an easier way - hook into the new motion events.

The main trick is that you need to have some UIView (not UIViewController) that you want as firstResponder to receive the shake event messages. Here's the code that you can use in any UIView to get shake events:

@implementation ShakingView

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
if ( event.subtype == UIEventSubtypeMotionShake )
// Put in code here to handle shake

if ( [super respondsToSelector:@selector(motionEnded:withEvent:)] )
[super motionEnded:motion withEvent:event];

- (BOOL)canBecomeFirstResponder
{ return YES; }


You can easily transform any UIView (even system views) into a view that can get the shake event simply by subclassing the view with only these methods (and then selecting this new type instead of the base type in IB, or using it when allocating a view).

In the view controller, you want to set this view to become first responder:

- (void) viewWillAppear:(BOOL)animated
[shakeView becomeFirstResponder];
[super viewWillAppear:animated];
- (void) viewWillDisappear:(BOOL)animated
[shakeView resignFirstResponder];
[super viewWillDisappear:animated];

Don't forget that if you have other views that become first responder from user actions (like a search bar or text entry field) you'll also need to restore the shaking view first responder status when the other view resigns!

This method works even if you set applicationSupportsShakeToEdit to NO.
In iOS 8.3 (perhaps earlier) with Swift, it's as simple as overriding the motionBegan or motionEnded methods in your view controller:

class ViewController: UIViewController {
override func motionBegan(motion: UIEventSubtype, withEvent event: UIEvent) {
println("started shaking!")

override func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent) {
println("ended shaking!")

Login / Signup to Answer the Question.

  • Be descriptive with your answer, and try to avoid copy-pasting external links, instead guide the user who has asked the question, where can they find the detailed answer.
  • You cannot share any URL in answer.
  • To make a text bold, surround the text with single asterisk, for example *bold text*
  • To format a text like code, surround the text within double asterisk, for example **code**
  • To add a multiline piece of code, surround the whole code within triple asterisk, for example *** multiline code ***
  • Please verify before submitting the answer.