Maybe the following code helps you. I found it a while back (don't remember where) and cleaned it up. You can tweak the values in didAccelerate, currently at 0.8 and 0.2 to define how sensitive it is to shaking and how stable you must hold the device to be able to shake again.
Header
@protocol ShakeHelperDelegate
-(void) onShake;
@end
@interface ShakeHelper : NSObject <UIAccelerometerDelegate>
{
BOOL histeresisExcited;
UIAcceleration* lastAcceleration;
NSObject<ShakeHelperDelegate>* delegate;
}
+(id) shakeHelperWithDelegate:(NSObject<ShakeHelperDelegate>*)del;
-(id) initShakeHelperWithDelegate:(NSObject<ShakeHelperDelegate>*)del;
@end
Implementation
#import "ShakeHelper.h"
@interface ShakeHelper (Private)
@end
@implementation ShakeHelper
// 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 AccelerationIsShaking(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);
}
+(id) shakeHelperWithDelegate:(NSObject<ShakeHelperDelegate>*)del
{
return [[[self alloc] initShakeHelperWithDelegate:del] autorelease];
}
-(id) initShakeHelperWithDelegate:(NSObject<ShakeHelperDelegate>*)del
{
if ((self = [super init]))
{
delegate = del;
[UIAccelerometer sharedAccelerometer].delegate = self;
}
return self;
}
-(void) accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
{
if (lastAcceleration)
{
if (!histeresisExcited && AccelerationIsShaking(lastAcceleration, acceleration, 0.8))
{
histeresisExcited = YES;
[delegate onShake];
}
else if (histeresisExcited && !AccelerationIsShaking(lastAcceleration, acceleration, 0.2))
{
histeresisExcited = NO;
}
}
[lastAcceleration release];
lastAcceleration = [acceleration retain];
}
-(void) dealloc
{
CCLOG(@"dealloc %@", self);
[UIAccelerometer sharedAccelerometer].delegate = nil;
[lastAcceleration release];
[super dealloc];
}
@end
You use it like this:
[ShakeHelper shakeHelperWithDelegate:self];
Obviously the self object needs to implement the ShakeHelperDelegate Protocol. The message onShake will be sent to the delegate object whenever a shake is detected.