Reputation: 2196
How do i set up a button (IBAction and UIButton attached) to continue to run the IBAction or a function while the button is being pressed, running a functioning continuously until the button is let up.
Should i attach a value changed receiver?
Simple question, but I can't find the answer.
Upvotes: 0
Views: 1732
Reputation: 28349
Add a dispatch source iVar to your controller...
dispatch_source_t _timer;
Then, in your touchDown action, create the timer that fires every so many seconds. You will do your repeating work in there.
If all your work happens in UI, then set queue to be
dispatch_queue_t queue = dispatch_get_main_queue();
and then the timer will run on the main thread.
- (IBAction)touchDown:(id)sender {
if (!_timer) {
dispatch_queue_t queue = dispatch_get_global_queue(
DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
// This is the number of seconds between each firing of the timer
float timeoutInSeconds = 0.25;
dispatch_source_set_timer(
_timer,
dispatch_time(DISPATCH_TIME_NOW, timeoutInSeconds * NSEC_PER_SEC),
timeoutInSeconds * NSEC_PER_SEC,
0.10 * NSEC_PER_SEC);
dispatch_source_set_event_handler(_timer, ^{
// ***** LOOK HERE *****
// This block will execute every time the timer fires.
// Do any non-UI related work here so as not to block the main thread
dispatch_async(dispatch_get_main_queue(), ^{
// Do UI work on main thread
NSLog(@"Look, Mom, I'm doing some work");
});
});
}
dispatch_resume(_timer);
}
Now, make sure to register for both touch-up-inside and touch-up-outside
- (IBAction)touchUp:(id)sender {
if (_timer) {
dispatch_suspend(_timer);
}
}
Make sure you destroy the timer
- (void)dealloc {
if (_timer) {
dispatch_source_cancel(_timer);
dispatch_release(_timer);
_timer = NULL;
}
}
Upvotes: 2
Reputation: 130193
[myButton addTarget:self action:@selector(buttonIsDown) forControlEvents:UIControlEventTouchDown];
[myButton addTarget:self action:@selector(buttonWasReleased) forControlEvents:UIControlEventTouchUpInside];
- (void)buttonIsDown
{
//myTimer should be declared in your header file so it can be used in both of these actions.
NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(myRepeatingAction) userInfo:nil repeats:YES];
}
- (void)buttonWasReleased
{
[myTimer invalidate];
myTimer = nil;
}
Upvotes: 3
Reputation: 745
UIButton should call a starting method with touchDown event and call ending method with touchUpInside event
Upvotes: 0