frankie
frankie

Reputation: 673

How can I get NSTimer to continue while adjusting timeInterval - iOS

I have a knob IBAction that adjusts the timeInterval of an NSTimer.

But I can't find a way to get the timer to continuously fire while adjusting the timeInterval. I guess this is because I am continuously invalidating and re-instancing the timer, right?

Is there a way to get it to work smoothly - so that the timer will accelerate/decelerate with the knob motions?

-(IBAction)autoSpeed:(UISlider *)sender
{
    timeInterval = (60/sender.value) / 4;

    if (seqState){
        [self changeTempo];
    }

    [self displayBPM:[sender value]:[sender isTouchInside]];
}

-(void) changeTempo
{
    if (repeatingTimer!= nil) {
        [repeatingTimer invalidate];
        repeatingTimer = nil;
        repeatingTimer = [NSTimer scheduledTimerWithTimeInterval: timeInterval target:self selector:@selector(changeAutoSpeedLed) userInfo:nil repeats:YES];

    }
    else
        repeatingTimer = [NSTimer scheduledTimerWithTimeInterval: timeInterval target:self selector:@selector(changeAutoSpeedLed) userInfo:nil repeats:YES];
}

Upvotes: 0

Views: 679

Answers (2)

IluTov
IluTov

Reputation: 6852

You can recreate the timer in the tick.


.h file

You have to make a property called interval.

@property NSTimeInterval interval; 

.m file

First, initialise it:

self.interval = 100;
[self timerTick];

Then you can use the timerTick method to recreate the timer if

- (void)timerTick {
    if (self.interval) {
        [self.timer invalidate];
        self.timer = [NSTimer scheduledTimerWithTimeInterval:self.interval target:self selector:@selector(timerTick) userInfo:nil repeats:YES];
        self.interval = 0;
    }


    // Do all the other stuff in the timer
}

Then you can set self.interval whenever you want and the timer will automatically be recreated.

Upvotes: 1

Guy Kogus
Guy Kogus

Reputation: 7341

The reason that it's not running smoothly is because you're using scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:, which, according to Apple's documentation:

Creates and returns a new NSTimer object and schedules it on the current run loop in the default mode.

The default mode is blocked by UI interaction, so if you're controlling the knob the timer is blocked. If you instead use code such as:

[[NSRunLoop currentRunLoop] addTimer:repeatingTimer forMode:NSRunLoopCommonModes];

then the code will not be blocked by UI.

Upvotes: 1

Related Questions