Rectangle 27 5

Sorry to post this as an answer rather than a comment but as you can see I'm new to Stack Overflow and so I'm not yet reputable enough to post comments!

Anyway I second @cire about making sure to set the first responder status once the view is part of the view hierarchy. So setting first responder status in your view controllers viewDidLoad method won't work for example. And if you're unsure as to whether it is working [view becomeFirstResponder] returns you a boolean that you can test.

Another point: you can use a view controller to capture the shake event if you don't want to create a UIView subclass unnecessarily. I know it's not that much hassle but still the option is there. Just move the code snippets that Kendall put into the UIView subclass into your controller and send the becomeFirstResponder and resignFirstResponder messages to self instead of the UIView subclass.

This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post.

@SashaSalauyou I clearly stated in the very first sentence here I didn't have enough reputation to post a comment at the time

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 287

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; }

@end

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).

- (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 didn't quite work for me: I needed to override my controller's viewDidAppear instead of viewWillAppear. I'm not sure why; maybe the view needs to be visible before it can do whatever it does to start receiving the shake events?

This is easier but not necessarily better. If you want to detect a long, continuous shake this approach is not useful as the iPhone likes to fire motionEnded before the shake has actually stopped. So using this approach you get a disjointed series of short shakes instead of one long one. The other answer works much better in this case.

@Kendall - UIViewControllers implement UIResponder and are in the responder chain. The topmost UIWindow is as well. developer.apple.com/library/ios/DOCUMENTATION/EventHandling/

[super respondsToSelector:
[self respondsToSelector:
YES
[[ShakingView superclass] instancesRespondToSelector:

Instead of using: if ( event.subtype == UIEventSubtypeMotionShake ) you can use: if ( motion == UIEventSubtypeMotionShake )

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 33

I came across this post looking for a "shaking" implementation. millenomi's answer worked well for me, although i was looking for something that required a bit more "shaking action" to trigger. I've replaced to Boolean value with an int shakeCount. I also reimplemented the L0AccelerationIsShaking() method in Objective-C. You can tweak the ammount of shaking required by tweaking the ammount added to shakeCount. I'm not sure i've found the optimal values yet, but it seems to be working well so far. Hope this helps someone:

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    if (self.lastAcceleration) {
        if ([self AccelerationIsShakingLast:self.lastAcceleration current:acceleration threshold:0.7] && shakeCount >= 9) {
            //Shaking here, DO stuff.
            shakeCount = 0;
        } else if ([self AccelerationIsShakingLast:self.lastAcceleration current:acceleration threshold:0.7]) {
            shakeCount = shakeCount + 5;
        }else if (![self AccelerationIsShakingLast:self.lastAcceleration current:acceleration threshold:0.2]) {
            if (shakeCount > 0) {
                shakeCount--;
            }
        }
    }
    self.lastAcceleration = acceleration;
}

- (BOOL) AccelerationIsShakingLast:(UIAcceleration *)last current:(UIAcceleration *)current threshold:(double)threshold {
    double
    deltaX = fabs(last.x - current.x),
    deltaY = fabs(last.y - current.y),
    deltaZ = fabs(last.z - current.z);

    return
    (deltaX > threshold && deltaY > threshold) ||
    (deltaX > threshold && deltaZ > threshold) ||
    (deltaY > threshold && deltaZ > threshold);
}

PS: I've set the update interval to 1/15th of a second.

[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / 15)];

How can i detect the device movement just like as panorama?

How to identify shake if iphone is moved in X direction only? I don't want to detect shake if in Y or Z direction.

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 179

// Ensures the shake is strong enough on at least two axes before declaring it a shake.
// "Strong enough" means "greater than a client-supplied threshold" in G's.
static BOOL L0AccelerationIsShaking(UIAcceleration* last, UIAcceleration* current, double threshold) {
    double
        deltaX = fabs(last.x - current.x),
        deltaY = fabs(last.y - current.y),
        deltaZ = fabs(last.z - current.z);

    return
        (deltaX > threshold && deltaY > threshold) ||
        (deltaX > threshold && deltaZ > threshold) ||
        (deltaY > threshold && deltaZ > threshold);
}

@interface L0AppDelegate : NSObject <UIApplicationDelegate> {
    BOOL histeresisExcited;
    UIAcceleration* lastAcceleration;
}

@property(retain) UIAcceleration* lastAcceleration;

@end

@implementation L0AppDelegate

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    [UIAccelerometer sharedAccelerometer].delegate = self;
}

- (void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {

    if (self.lastAcceleration) {
        if (!histeresisExcited && L0AccelerationIsShaking(self.lastAcceleration, acceleration, 0.7)) {
            histeresisExcited = YES;

            /* SHAKE DETECTED. DO HERE WHAT YOU WANT. */

        } else if (histeresisExcited && !L0AccelerationIsShaking(self.lastAcceleration, acceleration, 0.2)) {
            histeresisExcited = NO;
        }
    }

    self.lastAcceleration = acceleration;
}

// and proper @synthesize and -dealloc boilerplate code

@end

The histeresis prevents the shake event from triggering multiple times until the user stops the shake.

What happens if they're shaking it precisely on a particular axis?

The best answer, because the iOS 3.0 motionBegan and motionEnded events are not very precise or accurate in terms of detecting the exact start and end of a shake. This approach allows you to be as precise as you want.

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 153

I finally made it work using code examples from this Undo/Redo Manager Tutorial. This is exactly what you need to do:

  • Set the applicationSupportsShakeToEdit property in the App's Delegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application {

        application.applicationSupportsShakeToEdit = YES;

        [window addSubview:viewController.view];
        [window makeKeyAndVisible];
}
  • Add/Override canBecomeFirstResponder, viewDidAppear: and viewWillDisappear: methods in your View Controller:
-(BOOL)canBecomeFirstResponder {
    return YES;
}

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self becomeFirstResponder];
}

- (void)viewWillDisappear:(BOOL)animated {
    [self resignFirstResponder];
    [super viewWillDisappear:animated];
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    if (motion == UIEventSubtypeMotionShake)
    {
        // your code
    }
}

Worked perfect for me in 3.1.3, thanks!

Just to add to Eran Talmor solution : you should use a navigationcontroller instead of a viewcontroller in case of you've choose such an application in new project chooser.

Yep, works. Even on iOS 4.2 on the iPad with a UISplitView

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 94

Now ... I wanted to do something similar (in iPhone OS 3.0+), only in my case I wanted it app-wide so I could alert various parts of the app when a shake occurred. Here's what I ended up doing.

First, I subclassed UIWindow. This is easy peasy. Create a new class file with an interface such as MotionWindow : UIWindow (feel free to pick your own, natch). Add a method like so:

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
    if (event.type == UIEventTypeMotion && event.subtype == UIEventSubtypeMotionShake) {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"DeviceShaken" object:self];
    }
}

Change @"DeviceShaken" to the notification name of your choice. Save the file.

Now, if you use a MainWindow.xib (stock Xcode template stuff), go in there and change the class of your Window object from UIWindow to MotionWindow or whatever you called it. Save the xib. If you set up UIWindow programmatically, use your new Window class there instead.

Now your app is using the specialized UIWindow class. Wherever you want to be told about a shake, sign up for them notifications! Like this:

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(deviceShaken) name:@"DeviceShaken" object:nil];

To remove yourself as an observer:

[[NSNotificationCenter defaultCenter] removeObserver:self];

I put mine in viewWillAppear: and viewWillDisappear: where View Controllers are concerned. Be sure your response to the shake event knows if it is "already in progress" or not. Otherwise, if the device is shaken twice in succession, you'll have a li'l traffic jam. This way you can ignore other notifications until you're truly done responding to the original notification.

Also: You may choose to cue off of motionBegan vs. motionEnded. It's up to you. In my case, the effect always needs to take place after the device is at rest (vs. when it starts shaking), so I use motionEnded. Try both and see which one makes more sense ... or detect/notify for both!

One more (curious?) observation here: Notice there's no sign of first responder management in this code. I've only tried this with Table View Controllers so far and everything seems to work quite nicely together! I can't vouch for other scenarios though.

Kendall, et. al - can anyone speak to why this might be so for UIWindow subclasses? Is it because the window is at the top of the food chain?

That's what's so weird. It works as-is. Hopefully it's not a case of "working in spite of itself" though! Please let me know what you find out in your own testing.

Momeks: If you need the notification to occur once the device is at rest (post-shake), use motionEnded instead of motionBegan. That ought to do it!

@Joe D'Andrea - It works as-is because UIWindow is in the responder chain. If something higher up the chain intercepted and consumed these events, it would not receive them. developer.apple.com/library/ios/DOCUMENTATION/EventHandling/

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 12

You need to check the accelerometer via accelerometer:didAccelerate: method which is part of the UIAccelerometerDelegate protocol and check whether the values go over a threshold for the amount of movement needed for a shake.

There is decent sample code in the accelerometer:didAccelerate: method right at the bottom of AppController.m in the GLPaint example which is available on the iPhone developer site.

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 9

#define kAccelerationThreshold      2.2

#pragma mark -
#pragma mark UIAccelerometerDelegate Methods
    - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration 
    {   
        if (fabsf(acceleration.x) > kAccelerationThreshold || fabsf(acceleration.y) > kAccelerationThreshold || fabsf(acceleration.z) > kAccelerationThreshold) 
            [self myShakeMethodGoesHere];   
    }

Also set the in the appropriate code in the Interface. i.e:

@interface MyViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource, UIAccelerometerDelegate>

How can i detect the device movement just like as panorama?

How to identify shake if iphone is moved in X direction only? I don't want to detect shake if in Y or Z direction.

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 10

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!")
    }
}

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 7

Add Following methods in ViewController.m file, its working properly

-(BOOL) canBecomeFirstResponder
    {
         /* Here, We want our view (not viewcontroller) as first responder 
         to receive shake event message  */

         return YES;
    }

    -(void) motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
    {
            if(event.subtype==UIEventSubtypeMotionShake)
            {
                    // Code at shake event

                    UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Motion" message:@"Phone Vibrate"delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
                    [alert show];
                    [alert release];

                    [self.view setBackgroundColor:[UIColor redColor]];
             }
    }
    - (void)viewDidAppear:(BOOL)animated
    {
             [super viewDidAppear:animated];
             [self becomeFirstResponder];  // View as first responder 
     }

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 7

Check out the GLPaint example.

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 4

First off, I know this is an old post, but it is still relevant, and I found that the two highest voted answers did not detect the shake as early as possible. This is how to do it:

  • Link CoreMotion to your project in the target's build phases:
  • In your ViewController: - (BOOL)canBecomeFirstResponder { return YES; } - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event { if (motion == UIEventSubtypeMotionShake) { // Shake detected. } }

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 3

Easiest solution is to derive a new root window for your application:

@implementation OMGWindow : UIWindow

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
    if (event.type == UIEventTypeMotion && motion == UIEventSubtypeMotionShake) {
        // via notification or something   
    }
}
@end

Then in your application delegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[OMGWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    //
}

If you are using a Storyboard, this may be trickier, I dont know the code you will need in the application delegate precisely.

And yes, you can derive your base class in the @implementation since Xcode 5.

This works, I use it in several apps. So not sure why it has been voted down.

worked like a charm. In case you're wondering, you can override the window class like this: stackoverflow.com/a/10580083/709975

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 1

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event{
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event{
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{

for details you may check a complete example code over there

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 8

If you want to use UIKit Dynamics, you can:

  • First, define a governing animator: @property (nonatomic, strong) UIDynamicAnimator *animator; And instantiate it: self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

Second, add attachment behavior to that animator for view in current location. This will make it spring back when the push is done. You'll have to play around with damping and frequency values.

UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:viewToShake attachedToAnchor:viewToShake.center];
attachment.damping = 0.5;
attachment.frequency = 5.0;
[self.animator addBehavior:attachment];

These values aren't quite right, but perhaps it's a starting point in your experimentation.

UIPushBehaviorModeInstantaneous
UIPushBehavior *push = [[UIPushBehavior alloc] initWithItems:@[viewToShake] mode:UIPushBehaviorModeInstantaneous];
push.pushDirection = CGVectorMake(100, 0);
[self.animator addBehavior:push];

Personally, I'm not crazy about this particular animation (the damped curve doesn't feel quite right to me). I'd be inclined use block based animation to move it one direction (with UIViewAnimationOptionCurveEaseOut), upon completion initiate another to move it in the opposite direction (with UIViewAnimationOptionCurveEaseInOut), and then upon completion of that, use the usingSpringWithDamping rendition of animateWithDuration to move it back to its original spot. IMHO, that yields a curve that feels more like "shake if wrong" experience.

magnificent, thanks @Rob. when you say "First add attachment behaviour" ... can you give me a hint, uh, which method I should be using to do that :) ?

I suppose using physics results in a springy feeling whereas I always equated the "wrong password" motion with a shake of someone's head... which is a more sustained and deliberate movement.

@nielsbot I agree. Shift it back and forth and spring it back when done if you want.

@NikhilMathew - Sorry about that; the OP was asking about UIKit Dynamics, so I presumed he was familiar with that, but for the benefit of people less familiar with the tech, I've incorporated your observation into my answer.

ios - Shake a UIView ... BUT using UIKit Dynamics - Stack Overflow

ios ios7 game-physics user-experience uikit-dynamics
Rectangle 27 0

Sorry to post this as an answer rather than a comment but as you can see I'm new to Stack Overflow and so I'm not yet reputable enough to post comments!

Anyway I second @cire about making sure to set the first responder status once the view is part of the view hierarchy. So setting first responder status in your view controllers viewDidLoad method won't work for example. And if you're unsure as to whether it is working [view becomeFirstResponder] returns you a boolean that you can test.

Another point: you can use a view controller to capture the shake event if you don't want to create a UIView subclass unnecessarily. I know it's not that much hassle but still the option is there. Just move the code snippets that Kendall put into the UIView subclass into your controller and send the becomeFirstResponder and resignFirstResponder messages to self instead of the UIView subclass.

This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post.

@SashaSalauyou I clearly stated in the very first sentence here I didn't have enough reputation to post a comment at the time

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

iphone ios accelerometer shake motion-detection
Rectangle 27 0

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event{
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event{
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{

for details you may check a complete example code over there

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

iphone ios accelerometer shake motion-detection
Rectangle 27 0

This blog describes a very simple shake detection using the DeviceMotionEvent listener:

window.addEventListener('devicemotion', function (e) {
    // This is where you put your code for dealing with the shake event here

    // Stop the default behavior from triggering the undo dialog (hopefully)
    e.preventDefault();
});

There is one other thing I can think of which would be to turn the text input into a readonly item after you are done with it. Presumably, a read only input field cannot make use of the undo function, though I haven't tested it. It's odd that the feature fires even after the input is no longer part of the DOM.

I'm not sure if preventing a shake action can be done through the -webkit- properties in CSS. Here is a list of webkit specific CSS properties (which may not contain 100% of the properties accessible).

Good idea, but no luck unfortunately. Even when attaching (or using Zepto's delegate function) the event to the input elements themselves, the Undo dialog still pops up.

Oh, and setting the input to readonly still makes the dialog pop up as well, unfortunately.

javascript - How to disable iOS "Shake to Undo" in a webapp - Stack Ov...

javascript ios ipad html5 iphone-web-app
Rectangle 27 0

For PhoneGap I just inserted this line: [UIApplication sharedApplication].applicationSupportsShakeToEdit = NO; in the webViewDidFinishLoad class and it worked wonders for me.

- (void)webViewDidFinishLoad:(UIWebView*)theWebView
{
    // Black base color for background matches the native apps
    theWebView.backgroundColor = [UIColor blackColor];

[UIApplication sharedApplication].applicationSupportsShakeToEdit = NO;

    return [super webViewDidFinishLoad:theWebView];
}

javascript - How to disable iOS "Shake to Undo" in a webapp - Stack Ov...

javascript ios ipad html5 iphone-web-app
Rectangle 27 0

@interface MyApplication : UIApplication

@end
@implementation MyApplication

- (void) sendEvent:(UIEvent *)event
{
    if( event && (event.subtype==UIEventSubtypeMotionShake))
    {
        AppDelegate *objAppDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

        [objAppDelegate doWhatEver];
        [super sendEvent:event];
    }
    else
    {
        [super sendEvent:event];
    }
}

@end

And the last step in main.m

int main(int argc, char *argv[])
{
return UIApplicationMain(argc, argv, NSStringFromClass([MyApplication class]), NSStringFromClass([AppDelegate class]));
}

This works in all cases.

iphone - Can I receive shake events in my AppDelegate? - Stack Overflo...

iphone ios uiapplicationdelegate uiresponder