hi i want iphone detect shake gesture only one time .
after iphone had been shaken and html files showed , then i want iphone doesn't detect shake anymore .
here is my code :
- (void)accelerometer:(UIAccelerometer *)accelerometer
didAccelerate:(UIAcceleration *)acceleration {
{
if (acceleration.x > kAccelerationThreshold
|| acceleration.y > kAccelerationThreshold
|| acceleration.z > kAccelerationThreshold) {
}
}
}
Remove the delegate:
[UIAccelerometer sharedAccelerometer].delegate = nil;
Related
I am writing an iPhone camera App. When user is about to take a picture, I would like to check if the iPhone is shaking and wait for the moment that there is no shaking and then capture the phone.
How can I do it?
Anit-shake feature is quite a complicated feature to pull off. I reckon it's a combination of some powerful blur detection/removal algorithms, and the gyroscope on iPhone.
You may start by looking into how to detect motion with the iPhone, and see what kind of results you can get with that. If it's not enough, start looking into shift/blur direction detection algorithms. This is not a trivial problem, but is something that you could probably accomplish given enough time. Hope that Helps!
// 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
I Googled it and found at How do I detect when someone shakes an iPhone?
I want to add a start button which will start the accelerometer, how can I set an IBAction to do that, in my code I use:
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
x.text = [NSString stringWithFormat:#"X is: %f", acceleration.x];
y.text = [NSString stringWithFormat:#"Y is: %f", acceleration.y];
z.text = [NSString stringWithFormat:#"Z is: %f", acceleration.z];
NSLog (#"Y = #%f", y.text);
}
-(IBAction)startPedometerPressed {
[startButton accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration];
}
This returns an error because of the undeclared identifier 'accelerometer'.
I'm sure there is something wrong in how I call the method but not sure what is it!
you have to write your accelerometer initialization code in the IBAction function. remove it from ViewDidLoad. now accelerometer works after the button pressed.
-(IBAction)startPedometerPressed
{
[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / kAccelerometerFrequency)];
[[UIAccelerometer sharedAccelerometer] setDelegate:self];
}
Hope this helps.
So I a little backstory. I wanted to implement a particle effect and sound effect that both last about 3 sec or so when the user shakes their iDevice. But first issue arrived when the build in UIEvent for shakes refused to work. So I took the advice of a few Cocos veterans to just use some script to get "violent" accelerometer inputs as shakes. Worked great until now.
The problem is that if you keep shaking it just stacks the particle and sounds over and over. Now this wouldn't be that big of a deal except it happens even if you are careful to try and not do so. So what I am hoping to do is disable the accelerometer when the particle effect/sound effect start and then reenable it as soon as they finish. Now I don't know if I should do this by schedule, NStimer, or some other function. I am open to ALL suggestions. here is my current "shake" code.
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
const float violence = 1;
static BOOL beenhere;
BOOL shake = FALSE;
if (beenhere) return;
beenhere = TRUE;
if (acceleration.x > violence * 1.5 || acceleration.x < (-1.5* violence))
shake = TRUE;
if (acceleration.y > violence * 2 || acceleration.y < (-2 * violence))
shake = TRUE;
if (acceleration.z > violence * 3 || acceleration.z < (-3 * violence))
shake = TRUE;
if (shake) {
id particleSystem = [CCParticleSystemQuad particleWithFile:#"particle.plist"];
[self addChild: particleSystem];
// Super simple Audio playback for sound effects!
[[SimpleAudioEngine sharedEngine] playEffect:#"Sound.mp3"];
shake = FALSE;
}
beenhere = FALSE;
}
UIAcceleration has a timestamp property. I would modify your code to save the current timestamp on a succesful shake in a static variable (perhaps static NSTimeInterval timestampOfLastShake?). Then modify if (shake) to if (shake && acceleration.timestamp - 3.0f >= timestampOfLastShake)
resulting code:
static NSTimeInterval timestampOfLastShake = 0.0f;
if (shake && acceleration.timestamp - 3.0f >= timestampOfLastShake ) {
timestampOfLastShake = acceleration.timestamp;
id particleSystem = [CCParticleSystemQuad particleWithFile:#"particle.plist"];
[self addChild: particleSystem];
// Super simple Audio playback for sound effects!
[[SimpleAudioEngine sharedEngine] playEffect:#"Sound.mp3"];
shake = FALSE;
}
You realize that you are doing single axis acceleration checks and you are not ensuring the acceleration is repeated (i.e. shake). In other words, if you drop your phone, your code will think it's someone shaking the device back-and-fourth few times (which is what a shake is) and fire many times a second. So, either apply multi-axis checks against time or simply use the shake UIEvent. All you will need to do is in your UIView (or UIWindow better yet), implement - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event making sure the view becomes first responder. This will take care of all acceleration filtering, etc. and app won't be bombarded by all the acceleration noise (you can drop your phone on the table and it won't mistake that for a shake).
Go here for doc: http://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MotionEvents/MotionEvents.html
Or:
- (BOOL)canBecomeFirstResponder {
return YES;
}
// Now call [self becomeFirstResponder]; somewhere, say in viewDidAppear of the controller.
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
if (event.subtype == UIEventSubtypeMotionShake) {
// You've got a shake, do something
}
}
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
}
I have developed an iPhone app which uses Shake Gesture to rotate the wheel of picker view. I am using IOS 3.2 as base sdk. I have a iPhone 3GS which is updated with IOS 4.0, when I execute my App in this 3GS phone it is working properly with Shake Gesture. but when I run it in iPhone 4 the Shake Gesture doesn't respond. I am not getting the reason of it, if anybody is having the Solotion please help me out... Below i am providing a code part which i hv used to handle Shake Gesture....
#define kRowMultiplier 20
#define kAccelerationThreshold 2.2
#define kUpdateInterval (1.0f/10.0f)
(void) accelerometer:(UIAccelerometer*)accelerometer didAccelerate: UIAcceleration*)acceleration{
if (fabsf(acceleration.x) > kAccelerationThreshold || fabsf(acceleration.y) > kAccelerationThreshold || fabsf(acceleration.z) > kAccelerationThreshold) {
[progressView startAnimating];
if (! isSpinning)
{
if(!btnRegion.selected && !btnFlavor.selected && !btnPrice.selected)
{
// Need to have it stop blurring a fraction of a second before it stops spinning so that the final appearance is not blurred.
[self stopBlurring];
wheelingTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(shufflePickerView) userInfo:nil repeats:YES];
}
else
{
[self shufflePickerView];
[self performSelector:#selector(stopBlurring) withObject:nil afterDelay:2.7];
}
}
isSpinning = YES;
}
}
is sumthing wrong in code... Can I test it by Simulator on IOS 4.0 or i need to hv a iPhone 4 only...?
Thanks Hugo for the Solution, But i got another way to do it before many days n I guess its quite easy...
we can do it by this way...
-(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{
if (event.type == UIEventSubtypeMotionShake)
{
//Put your code here what you want to do on a shake...
}
}
I have the exact same problem.
My code tested on an iPhone 3G works fine, on an iPhone 4 it doesn't work. Both running on iOS 4.2.1
UPDATE: Used this method and it works great:
http://www.softvelopment.com/index.php/blogs/2010/03/19/3-adding-shake-recongnition-to-cocos2d-iphone-library-
I know how to do shake for the iPhone has been asked a million times on here, but I can't seem to find anything useful regarding the accelerometer with Cocos2D. Everything i have found involves using views and I don't think i am using any views in Cocos2D, if I am they are hidden from me I think. I want to be able to tell when any sort of shake has occured within a CCLayer class?
I figured it out. In the layer class you need to put these lines;
self.isAccelerometerEnabled = YES;
[[UIAccelerometer sharedAccelerometer] setUpdateInterval:1/60];
shake_once = false;
Then implement this function in the layer class;
-(void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
float THRESHOLD = 2;
if (acceleration.x > THRESHOLD || acceleration.x < -THRESHOLD ||
acceleration.y > THRESHOLD || acceleration.y < -THRESHOLD ||
acceleration.z > THRESHOLD || acceleration.z < -THRESHOLD) {
if (!shake_once) {
int derp = 22/7;
shake_once = true;
}
}
else {
shake_once = false;
}
}
shake_once is just a boolean to stop one shake from being registered more than once.