Is this the right way to check AVAudioPlayer's current playback time.
[audioPlayer play];
float seconds = audioPlayer.currentTime;
float seconds = CMTimeGetSeconds(duration);
How I can code after
[audioPlayer play];
that when currentTime is equal to 11 seconds then
[self performSelector:#selector(firstview) withObject:nil];
and after firstview when currentTime is equal to 23 seconds
[self performSelector:#selector(secondview) withObject:nil];
You could set up a NSTimer to check the time periodically. You would need a method like:
- (void) checkPlaybackTime:(NSTimer *)theTimer
{
float seconds = audioPlayer.currentTime;
if (seconds => 10.5 && seconds < 11.5) {
// do something
} else if (seconds >= 22.5 && seconds < 23.5) {
// do something else
}
}
Then set up the NSTimer object to call this method every second (or whatever interval you like):
NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(checkPlaybackTime:)
userInfo:nil
repeats:YES];
Check the NSTimer documentation for more details. You do need to stop (invalidate) the timer at the right time when you're through with it:
https://developer.apple.com/documentation/foundation/nstimer
EDIT: seconds will probably not be exactly 11 or 23; you'll have to fiddle with the granularity.
Related
My timer does not stop even if i am doing "invalidate" and "nil" after reading other links. My code is as below:
#property(nonatomic,strong) NSTimer *mytimer;
- (void)viewDidLoad {
[self performSelectorOnMainThread:#selector(updateProgressBar:) withObject:nil waitUntilDone:NO];
<do some other work>
}
- (void) updateProgressBar :(NSTimer *)timer{
static int count =0;
count++;
NSLog(#"count = %d",count);
if(count<=10)
{
self.DownloadProgressBar.progress= (float)count/10.0f;
}
else{
NSLog(#"invalidating timer");
[self.mytimer invalidate];
self.mytimer = nil;
return;
}
if(count <= 10){
NSLog(#"count = %d **",count);
self.mytimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(updateProgressBar:) userInfo:nil repeats:YES];
}
}
1) The timer goes on infinetly even when invalidating timer else condition is hit after count >10 and count keeps on incrementing.
2) i want to do this on a non-main thread . i want to continue in viewdidload() after starting the timer. How to do this ?
I visited other links on SO, all i understood was to call invalidate and nil on timer pointer. I am still facing problems. Could anyone tell me what i am missing here and what i can i do to run the updateProgressBar on background thread and update the progress bar ?
don't need to schedule a timer each time, schedule it once and timer will fire every second for example u can do like below,
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelectorOnMainThread:#selector(startTimerUpdate) withObject:nil waitUntilDone:NO]; //to start timer on main thread
}
//hear schedule the timer
- (void)startTimerUpdate
{
self.mytimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(updateProgressBar:) userInfo:nil repeats:YES];
}
- (void) updateProgressBar :(NSTimer *)timer{
static int count =0;
count++;
NSLog(#"count = %d",count);
if(count<=10)
{
//self.DownloadProgressBar.progress= (float)count/10.0f;
NSLog(#"progress:%f",(float)count/10.0f);
}
else
{
NSLog(#"invalidating timer");
[self.mytimer invalidate];
self.mytimer = nil;
return;
}
if(count <= 10){
NSLog(#"count = %d **",count);
}
}
I think you are scheduling timer multiple time. I think 10 time. just schedule time one time or if require many time then invalidate it that many time as schedule.
Update according to comment : Schedule timer from viewdidload and addobserver means notification on task. when your task will completed invalidate timer. and update your progress in selector method of timer so when you invalidate it it will automatically stop progress bar.
Second thing : you should invalidate timer before moving another viewcontroller also because this objects remains live untill invalidate.
Hope this will hellp :)
I'm using NSTimer to display seconds on a label while recording.
I'm starting the timer when the record button is tapped and stopping it when the stop button is tapped.
When I tap the play button the timer is not restarting.
-(void)startTimer
{
playTimer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(timerController)
userInfo:nil
repeats:YES];
}
- (NSString*)getTimeStr : (int) secondsElapsed
{
seconds = secondsElapsed % 60;
int minutes = secondsElapsed / 60;
int hours = secondsElapsed/3600;
return [NSString stringWithFormat:#"%02d:%02d:%02d", hours, minutes, seconds];
}
- (void)timerController{
seconds++;
[[self timeLabel] setText:[self getTimeStr:(seconds)]];
}
- (IBAction)recordTapped:(id)sender {
[self startTimer];
}
- (IBAction)stopTapped:(id)sender {
[playTimer invalidate];
playTimer=nil;
_timeLabel.text=#"00:00:00";
}
- (IBAction)playTapped:(id)sender {
[self startTimer];
}
As mentioned in the comments, there are two bugs around:
Bug #1
You should always reset the variable seconds to 0 before restarting the timer (probably reset it at the 1st line of startTimer)
Bug #2
The variable seconds is overwritten by the 1st line of getTimeStr function. You should replace seconds with int sec and for the return line, replace seconds with sec.
- (void)resetTimer {
if(playTimer) {
[playTimer invalidate];
playTimer = nil;
}
}
You should call resetTimer method every time before startTimer again.
I created a timer, and was wondering if it is at all possible to make the timer go slower when it reaches a certain second: 1..2..3..4..4.1..4.2.
For example, the timer is increasing by 1 second, then at 4 seconds, the time slows down showing milliseconds.
if(i = 4) {
}
It depends on what you want.
Of course, you can't slow down the time, but you can simulate it.
For example, you check how much time has already passed. If it is 1, 2, 3 seconds, you NSLog 1, 2, 3. Then when 4 seconds has passed, you start logging milliseconds.
E.g.
if (i < 4) {
NSLog(#"%d", i);
} else {
NSLog(#"4.%d", i - 4);
}
Sure, logging can be substituted with whatever you need.
P.S. The answer is in Objective-C, but that changes nothing.
You can use a solution like this:
Declare a float to register your time and a NSTimer to perform the action.
#property NSTimer *timer;
#property float time;
Call startTimer to start the actions.
- (void) startTimer {
self.timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(secondsAction)
userInfo:nil
repeats:YES];
}
- (void) secondsAction {
self.time += 1;
NSLog(#"%d", (int)self.time);
if(self.time == 4) {
[self.timer invalidate];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1
target:self
selector:#selector(milisecondsAction)
userInfo:nil
repeats:YES];
}
}
- (void) milisecondsAction {
self.time += 0.1;
NSLog(#"%.1f", self.time);
}
How can I create a simple timer which will give me simply the Time in millisecond. Something like the following...
Timer *timer = [Timer alloc] init];
[timer start]; //Which will start from Zero
[timer pause]; //Which will Pause timer
[timer stop]; //Which will stop the timer
[timer getCurrentTime]; //Which will give me time elapsed in millisecond since [timer start] is called
NSTimer doesn't seem to Work as it provides more functionality but not this. Can I get this functionality using NSTimer? What would be the best way to achieve this?
NOTE: I don't want to call any function at any specific time period but just want the milliseconds since the timer started.
Why do you need a timer for that?
Just store the start time and subtract it from the current time when you stop measuring:
static NSTimeInterval startTime;
static BOOL isRunning;
- (IBAction)toggle:(id)sender
{
if(!isRunning)
{
startTime = [NSDate timeIntervalSinceReferenceDate];
isRunning = YES;
}
else
{
NSLog(#"%f", ([NSDate timeIntervalSinceReferenceDate] - startTime) * 1000.0);
isRunning = NO;
}
}
Actually i Was looking for this but somehow i missed this question
How Do I write a Timer in Objective-C?
I have a void function which just have NSLog(#"Call me"); in its body.
I call it in my view in every ten seconds by using
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:#selector(yourMethod) userInfo:nil repeats:YES];
But I want it to stop it after 5 iterations. However it goes to infinity. How can I do that?
1) Keep a global variable, that increments from 0 to 5.
int i = 0;
2) Incement this variable inside your timer function..
-(void) yourFunction:(NSTimer*)timer{
//do your action
i++;
if(i == 5){
[timer invalidate];
}
}
3) When creating timer
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:10
target:self
selector:#selector(yourMethod:) // <== see the ':', indicates your function takes an argument
userInfo:nil
repeats:YES];
You should take one counter, increment it every time when your method get called, count for 5 and then invalidate your timer using below code.
[timer invalidate];
To destroy the timer from the current loop, you should call [timer invalidate];
To determine five occurrences, you need to maintain a variable and increment its count each time. If it is equal to 5, call invalidate method.
First of all you need to declare an int and declare your NSTimer *timer, so we can stop it:
#interface AppDelegate : UIViewController {
int myInt;
NSTimer *timer;
}
To start the NSTimer you'll need to change just a bit of the code:
timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:#selector(yourMethod) userInfo:nil repeats:YES];
Inside your void function you can make the verification to check if the code's running after 5 iterations:
- (void)myVoid{
NSLog(#"Call Me");
if (myInt == 5) {
[timer invalidate];
timer = nil;
}
myInt++;
}