2009-06-23 34 views
13

私はカウントダウンを取るカウントダウンタイマーを作成しようとしているが、IBOutletは、私が60に繰り返しを制限するカウントダウンタイマー

A.どうかわからないダウン0に60秒から、テキストフィールドに接続されていますそして

B. advanceTimerでカウントダウンをデクリメントする方法:あなたがこれまでに正しい軌道に乗っている

- (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]; 
} 

答えて

19

を。ここでは、あなたが既に持っているコードにこだわっ

advanceTimer方法はそれを動作させるためにどのように見えるべきかです:

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

編集: 全体のことより、オブジェクト指向を行うには、との変換を避けるために文字列から数字とバックするたびに、私の代わりにこのようなものだろう:

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

そして、あなたはバインディングを利用することができるならば、あなたは単にテキストフィールドのintValueControllercounterプロパティにバインドすることができます。これにより、クラスインターフェイスでIBOutletを削除し、advanceTimersetIntegerValue:行を削除することができます。

更新:タイマを実行ループに2回追加するコードを削除しました。そのエラーに気付いたNikolai Ruheとnschmidtに感謝します。

更新:setIntegerValueメソッドを使用して、nschmidtのコードを簡略化しました。

編集:(空)advanceTimerの定義における誤植:(NSTimer *)タイマー...迷惑な「認識されていないセレクタがインスタンスに送信された」例外を発生させた

+0

countdownTimerが実行ループに2回追加されていますが、これは間違っています。 –

+0

@Nikolai Ruhe:それを指摘していただきありがとうございます。私は私の例から間違ったコードを削除しました。 –

+0

setIntegerValueは[NSString stringWithFormat:]よりも効率的だと思いますので、この「最適化」は行っていません。特に、コードの明瞭性には役立ちません。 – nschmidt

6

あなたは保持するために、インスタンス変数はint _timerValueを追加することができますタイマーの値を入力し、次の操作を行います。また、作成しているNSTimerは、すでに実行中のループでスケジュールされていることにも注意してください。

- (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]; 
} 
関連する問題