如何使用NSTimer更新标签?

时间:2013-09-29 17:48:31

标签: iphone ios objective-c

我有一个标签,我希望在重新编码触摸的一段时间内用多个显示器更新它的文本。我可以使用performSelector但它看起来很笨......

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self changeTextForLabel:@"A text (1)"]; // When touch begins the display is changed
[self performSelector:@selector(changeTextForLabel:) withObject:@"Another text (2)" afterDelay:1];               // After 1 second update to this
[self performSelector:@selector(changeTextForLabel:) withObject:@"And another text (3)" afterDelay:2];           // after 2 seconds update to this
[self performSelector:@selector(changeTextForLabel:) withObject:@"And even another text (4)" afterDelay:3];      // After 3 seconds update to this
[self performSelector:@selector(changeTextForLabel:) withObject:@"And yes even another text (5)" afterDelay:3]; }  

我听说人们谈论每隔x秒使用计时器执行一个方法,但我不明白如何在我的情况下使用它。我拥有的是......

- (void)updateLabel:(NSTimer *)theTimer {
[self changeTextForLabel:@"A text (1)"];
[self changeTextForLabel:@"Another text (2)"];
[self changeTextForLabel:@"And another text (3)"];
[self changeTextForLabel:@"And even another text (4)"];
[self changeTextForLabel:@"And yes even another text (5)"];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateLabel:) userInfo:nil repeats:YES]; }

但这仅显示最后一条消息..但我想让它在1秒后一个接一个地显示。 我尝试在每条消息之间使用pause()或sleep(),但它只会延迟标签更新之前的时间,并且会使用最后一条消息进行更新。

2 个答案:

答案 0 :(得分:0)

添加NSTimer属性

@property (nonatomic, strong) NSTimer *timer;

启动计时器的功能:

-(void) startTimer
{
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                  target:self
                                                selector:@selector(timerTick:)
                                                userInfo:nil
                                                 repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
    [self.timer fire];
}

计时器刻度事件获取当前时间:

//Event called every time the NSTimer ticks.
- (void)timerTick:(NSTimer *)timer
{

    Date *currentTime = [NSDate date];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setTimeStyle:NSDateFormatterLongStyle];
    NSString *timeNow = [dateFormatter stringFromDate:value];;

    [self updateDisplay:timeNow];
}

需要更新主线程上的显示:

-(void)updateDisplay:(NSString *)str
{
    //NSLog(@"update display: %@", str);
    [self performSelectorOnMainThread:@selector(setLabelText:)
                           withObject:str
                        waitUntilDone:YES];
    [self setNeedsDisplay];
}

设置标签文字:)

-(void) setLabelText:(NSString *)labelText
{
    [self.label setText:labelText];
}

答案 1 :(得分:0)

这是因为您在不等一秒钟的情况下更新每个标签。尝试这样的事情:

@property (nonatomic) NSArray* titles;

...

- (NSArray*) titles {
    if(!_titles)
        _titles= @[@"A text (1)", @"Another text (2)", @"And another text (3)", @"And even another text (4)", @"And yes even another text (5)"];
    return _titles;
}

- (void)updateLabel:(NSTimer *)theTimer {
    if(self.titles.count)
    {
        [self changeTextForLabel: self.titles[0] ];
        // Alternatively use a NSMutableArray
        self.titles= [self.titles subarrayWithRange: NSMakeRange(1,self.titles.count-1) ];
    }
    else { // Invalidate the timer
    }
}

如果您想重新初始化数组以再次显示所有标题,那么将titles设置为nil就足够了,以便下次调用getter时,数组将再次初始化:

self.titles= nil;  // Now _titles is nil
self.titles; // Not it's the full array with all the 5 objects

替代

- (void)updateLabel:(NSTimer *)theTimer {
    static unsigned int count=0;
    [self changeTextForLabel: self.titles[count++ % self.titles.count] ];
    if(count==5) {
        // Invalidate the timer
    }
}

PS:使用最后一段代码,您无需重置阵列。当count溢出时,它将重新启动为零,因此它稳定且安全。