For example, let's say that some variable changes based on user input. When this variable reaches some condition, it must hold that condition for some set time before some other code is executed.
if(changingVariable == someValue for some amount of time){
//code to be executed
}
NOTE: I want the answer to be as general as possible so that it can be applied to any situation.
For some context, here is the situation that I will be using it in:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (CMMotionManager *)motionManager {
_motionManager = [[CMMotionManager alloc] init];
_motionManager.accelerometerUpdateInterval = 0.1;
return _motionManager;
}
- (IBAction)takePhoto:(UIButton *)sender {
[self isStable];
}
- (void)isStable {
if(!self.motionManager.isAccelerometerActive) {
[self.motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accData, NSError *error){
CGFloat x = accData.acceleration.x;
CGFloat y = accData.acceleration.y;
//CGFloat z = accData.acceleration.z;
}];
// This is the condition that needs to hold true
// for half of a second before executing some code
if(fabs(x) < .095 && fabs(y) < .095){
// Code that takes a picture
}
}
}
@end
Edit: I just want to say thanks to all who helped!
Being unaware of your real intention, I'm proposing a bridged solutions covering up the scenarios.
First declare x
and y
as class properties
@property(nonatomic) CGFloat x;
@property(nonatomic) CGFloat y;
@property(nonatomic) BOOL scheduled;
...
Next modify your motion manager update code like this
[motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accData, NSError *error){
self.x = accData.acceleration.x;
self.y = accData.acceleration.y;
// This is the condition that needs to hold true
// for half of a second before executing some code
if(fabs(self.x) < .095 && fabs(self.y) < .095) {
//schedule your takePicture routine to be executed after 0.5 seconds
//if not already scheduled
if (!self.scheduled) {
[self performSelector:@selector(takePicture) withObject:nil afterDelay:0.5];
self.scheduled = YES;
}
}
/*
else {
//cancel previously scheduled method
//if the condition doesn't hold true in an intermediate update
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(takePicture) object:nil];
//reset the flag so that further scheduling is possible
self.scheduled = NO;
}
*/
}];
And now in your takePicture
routine reevaluate the condition and execute code only if the condition is true:
-(void)takePicture {
if (fabs(self.x) < .095 && fabs(self.y) < .095) {
// Code that takes a picture
}
//reset the flag so that further scheduling is possible
self.scheduled = NO;
}
So to summarize things:
takePicture
routine after 0.5 secondstakePicture
routine reevaluate the condition and if it still holds
true we execute capture code.So what's left? Here we have considered only the terminal conditions -- we evaluated the condition just before 0.5 seconds interval commences and just after it ends. But it doesn't guarantee the condition holds true
in between. If we also need to conform to this scenario, we need to cancel the previously scheduled routine if the condition deviates from its true
state and that can be achieved by uncommenting the else
block in motion manager update portion that I've commented out for the time being.