2013-09-29 31 views
1

我有一個標籤,我想在觸摸重新編碼的一段時間內用多個顯示器更新文本。我可以使用performSelector但似乎笨重......如何使用NSTimer更新標籤?

- (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(),但它只會延遲標籤更新之前的時間,並會使用最後一條消息進行更新。

回答

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 
    } 
} 

,這是不夠的,你設置titlesnil,所以下一次你打電話,吸氣時,陣列將被再次初始化:

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:有了這個最C您不需要重置陣列。當count溢出時,它將重新啓動爲零,因此它穩定且安全。

+0

在 - (NSArray)標題方法,如果我使用self.titles它崩潰。你知道爲什麼嗎? 另外,當顯示完成時,我怎樣才能讓它再次通過顯示器,當我點擊? –

+0

Inside - (NSArray *)標題,如果您使用self.titles你崩潰,因爲self.titles調用 - (NSArray *)標題;點符號只是調用getter/setter的快捷方式。所以你會因爲你遞歸調用getter而崩潰,遞歸永遠不會結束。使用_titles而不是self.titles。 –

+0

要再次顯示5個標題,您需要重置titles數組。您只需將標題設置爲零即可完成此操作,以便當您再次調用self.titles時,該數組將被重新初始化。我編輯了答案,使其更清晰。 –

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

scheduledTimerWithTimeInterval已經將計時器添加到運行循環中,您不需要再次添加它。 –

+0

@RamyAlZuhouri謝謝,它也會觸發它嗎? – Danpe

+1

是的,它也會觸發它。 –