6

I've been trying to get a timer to show at the bottom left corner of my app by using an NSTimer, and making the "elapsed time" show as UILabel on the bottom left corner but it hasn't been working for me.

-(void)viewDidLoad
{
    NSTimer *aTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(aTime) userInfo:nil repeats:YES];
}

-(void)aTime
{
    NSLog(@"....Update Function Called....");

    static int i = 1;

    Label.text = [NSString stringWithFormat:@"%d",i];

    i++;
}

The timer actually works but I can't get it to be triggered by a button. I'm trying to get the timer to continue and not restart at 1 when it enters to the next storyboard/xib file.

jscs
  • 63,694
  • 13
  • 151
  • 195
user1677210
  • 169
  • 1
  • 1
  • 13
  • 6
    Can you please include your code so that we may look at it to determine why it is not working? – vcsjones Sep 21 '12 at 16:04
  • Sorry for that. I was experimenting with different codes trying to see if I could make things work so I didn't really have a code to post a while back cause they were kind of just drafts. But I posted the code I'm using now. Hope that helps! Thanks. – user1677210 Sep 21 '12 at 16:39
  • @user1677210: now what is the issue ? Timer is not working or need to implement it in button click ? – Midhun MP Sep 21 '12 at 16:42
  • If you want it triggered by a button, then put the timer creation code in the button method, not viewDidLoad. – rdelmar Sep 21 '12 at 16:43
  • @MidhunMP the only issue now is how do I get the Timer to continue on even after going to another storyboard/xib. Like if it ends at 10 on the first storyboard/xib file it should continue to 11 at the next. – user1677210 Sep 21 '12 at 16:48

2 Answers2

11

For implementing the timer action on the button press, you need to write it on a IBAction method like:

- (IBAction) buttonPress
{
    NSTimer *aTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(aTime) userInfo:nil repeats:YES];
}

For storing the previous value, you can use NSUserDefaults or a SQLite database. For this purpose I'll suggest NSUserDefaults.

Change the aTime method like:

-(void)aTime
{
    NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
    id obj = [standardUserDefaults objectForKey:@"TimerValue"];
    int i = 0;

    if(obj != nil)
    {
        i = [obj intValue];
    }

    Label.text = [NSString stringWithFormat:@"%d",i];
    i++;

    [standardUserDefaults setObject:[NSNumber numberWithInt:i] forKey:@"TimerValue"];
    [standardUserDefaults synchronize];
}
Adi Inbar
  • 12,097
  • 13
  • 56
  • 69
Midhun MP
  • 103,496
  • 31
  • 153
  • 200
3

I think the problem is that the method aTime is in your view controller, when you enters another view, this view controller is released and you can't perform selector aTime anymore.

so I suggest that you put your aTime method and i to a singleton(or any object that won't be released when you enter another view) and set the singleton as the target of your timer.

also you should keep code below in your view controller so that you can update your label properly when you came back to this view.

-(void)viewDidLoad
{
    NSTimer *aTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(aTime) userInfo:nil repeats:YES];
}

-(void)aTime
{
    NSLog(@"....Update Function Called....");

    Label.text = [NSString stringWithFormat:@"%d",theSingleton.i];
}

better choice:

You can declare i as a property of your singleton, and then add an observer to i, then you'll get your label updated on time. call -startTimer when you want to count time.

the singleton:

  @interface Singleton

  @property (nonatomic,retain) NSNumber *i;

  @end

  @implementation

+(Singleton*)instance
{
    //the singleton code here
}

-(void)startTimer
{
    NSTimer *aTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(aTime) userInfo:nil repeats:YES];
}

-(void)aTime
{
    NSInteger temp = [i integerValue];
    temp ++;
    self.i = [NSNumber numberWithInteger:temp];
}

the view controller:

-(void)viewDidLoad
{
    [super viewDidLoad];
    [[Singleton instance] addObserver:self forKeyPath:@"i" options:NSKeyValueObservingOptionNew context:NULL]];
}


- (void)observeValueForKeyPath:(NSString *)keyPath
                  ofObject:(id)object
                    change:(NSDictionary *)change
                   context:(void *)context
{
    NSLog(@"....Update Function Called....");

    Label.text = [NSString stringWithFormat:@"%@",[Singleton instance].i];
}
Adrian P
  • 6,479
  • 4
  • 38
  • 55
CarmeloS
  • 7,868
  • 8
  • 56
  • 103
  • Thans for the help man. Singletons are pretty much new to me. I understand it in theory but I get lost a bit with the coding. How do I set up a Singleton for the time data? – user1677210 Sep 21 '12 at 17:25
  • You don't have to use a singleton then, you can just put i as a property in your application delegate. – CarmeloS Sep 22 '12 at 00:34