jesteś na dobrej drodze do tej pory.
Kłucie z kodem już masz, oto jak advanceTimer
metoda powinna wyglądać, aby to działało:
- (void)advanceTimer:(NSTimer *)timer
{
[countdown setIntegerValue:([countdown integerValue] - 1)];
if ([countdown integerValue] == 0)
{
// code to stop the timer
}
}
edit: Aby cała sprawa bardziej zorientowanym obiektowo i aby uniknąć konwersja z ciągów liczb i do tyłu za każdym razem, chciałbym zamiast zrobić coś takiego:
// 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
I, jeśli można skorzystać z wiązaniami, można po prostu powiązać pole tekstowe na intValue
do majątku Controller
counter
. Umożliwi to wyeliminowanie interfejsu IBOutlet
w interfejsie klasy i linii setIntegerValue:
w advanceTimer
.
Aktualizacja: aktualizacja: Usunięto kod, który dwukrotnie dodaje timer do pętli uruchamiania. Dziękuję Nikolai Ruhe i nschmidtowi za zauważenie tego błędu.
aktualizacja: Zastosowano metodę setIntegerValue
, aby uprościć kod, zgodnie z nschmidt.
edit: Typo w definicji (void) advanceTimer: (*) NSTimer czasomierz ... spowodowane irytujące 'nierozpoznany selektor wysyłane do instancji' wyjątku
CountdownTimer jest dodawany dwukrotnie do pętli uruchamiania, co jest błędem. –
@Nikolai Ruhe: Dziękuję za wskazanie tego. Usunąłem niepoprawny kod z moich przykładów. –
Domyślam się, że setIntegerValue jest bardziej wydajne niż [NSString stringWithFormat:], więc nie zrobiłbym tej "optymalizacji". Zwłaszcza, że nie pomaga to w jasności kodu. – nschmidt