2009-06-23 23 views
13

Ben geri sayım götüren bir geri sayım sayacı oluşturmak çalışıyorum, bir IBOutlet ben 60 tekrarlarını sınırlamak içinGeri Sayım

A. Nasıl emin değilim aşağı 0'a 60 saniye arasında, bir textfield bağlı ve

B. advanceTimer içinde geri sayımı azaltma nasıl: O ana dek doğru yoldayız

- (IBAction)startCountdown:(id)sender 
{ 
    NSTimer *countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self  selector:@selector(advanceTimer:) userInfo:nil repeats:YES]; 
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; 
    [runLoop addTimer:countdownTimer forMode:NSDefaultRunLoopMode]; 
} 

- (void)advanceTimer:(NSTimer *)timer 
{ 
    [countdown setIntegerValue:59]; 
} 

cevap

19

.

- (void)advanceTimer:(NSTimer *)timer 
{ 
    [countdown setIntegerValue:([countdown integerValue] - 1)]; 
    if ([countdown integerValue] == 0) 
    { 
     // code to stop the timer 
    } 
} 

düzenleme: Zaten sahip koduyla tutunan

, burada advanceTimer yöntem çalışması için bakmak gerekir nasıl yapmak için her şeyi nesne yönelimli daha ve dönüştürme önlemek için sayılara dizeleri ve arka her zaman, bunun yerine böyle bir şey yapacağını:

// Controller.h: 
@interface Controller 
{ 
    int counter; 
    IBOutlet NSTextField * countdownField; 
} 
@property (assign) int counter; 
- (IBAction)startCountdown:(id)sender; 
@end 

// Controller.m: 
@implementation Controller 

- (IBAction)startCountdown:(id)sender 
{ 
    counter = 60; 

    NSTimer *countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1 
             target:self 
             selector:@selector(advanceTimer:) 
             userInfo:nil 
             repeats:YES]; 
} 

- (void)advanceTimer:(NSTimer *)timer 
{ 
    [self setCounter:(counter -1)]; 
    [countdownField setIntegerValue:counter]; 
    if (counter <= 0) { [timer invalidate]; } 
} 

@end 

Ve, bağlamaları yararlanabilir eğer, sadece metin alanı en intValueController ait counter özelliğine bağlanabilir. Bu, sınıf arabirimindeki IBOutlet ve 'daki setIntegerValue: satırını elemenize olanak tanır.

güncelleme: Zamanlayıcıyı çalışma döngüsüne iki kez ekleyen kodu kaldırıldı. Bu hatayı fark ettiğin için Nikolai Ruhe ve nschmidt'e teşekkür ederim.

Güncelleme: Kodu basitleştirmek için, nschmidt'e göre setIntegerValue yöntemini kullandık.

düzenleme: (boşluk) advanceTimer tanımında Typo: (NSTimer *) zamanlayıcı ... can sıkıcı

+0

CountdownTimer, çalışma döngüsüne iki kez eklenir, bu yanlıştır. –

+0

@Nikolai Ruhe: Bunu işaret ettiğiniz için teşekkür ederim. Yanlış kodu örneklerimden kaldırdım. –

+0

Sanırım setIntegerValue, [NSString stringWithFormat:] değerinden daha verimlidir, bu yüzden bu "optimizasyon" işlemini yapmazdım. Özellikle de kodun açıklığına yardımcı olmadığından. – nschmidt

6

Sen tutmak için bir örnek değişkeni int _timerValue ekleyebilir istisna 'tanınmadı seçici örneğine gönderilen' neden Zamanlayıcı değerini ve ardından aşağıdakileri yapın. Ayrıca, oluşturduğunuz NSTimer'in halihazırdaki çalışma döngüsü üzerinde planlanmış olduğunu unutmayın.

- (IBAction)startCountdown:(id)sender 
{ 
    _timerValue = 60; 
    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(advanceTimer:) userInfo:nil repeats:NO]; 
} 

- (void)advanceTimer:(NSTimer *)timer 
{ 
    --_timerValue; 
    if(self.timerValue != 0) 
     [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(advanceTimer:) userInfo:nil repeats:NO]; 

    [countdown setIntegerValue:_timerValue]; 
} 
İlgili konular