2012-05-12 10 views
1

私はXcode 4.3.1を使用してIphone用のアプリケーションをプログラミングしようとしていますが、私はボタンを押してタッチスクリーンのどこかに触れ、ラベル(タイマー付き)が表示され、いくつかの数値からカウントダウンします。タイマーが0:00になったら、それを無効にして、これを行うには参照を保持する必要があります。自己無効化する複数のタイマーを作成する

私は手前で使用するラベル/タイマーの総数がわからないので、それぞれを格納するために配列を使用すると思っていました。私はObjective-C言語の知識がほとんどありません。私がこれまで行ってきたことは、他のstackoverflowの質問で見た例を複製し、理解しようとしています。私はこれまで比較的機能的なタイマーを構築することができました。

以下は私のタイマー用の私の現在のコードです。現在のところ、あらかじめ作成されたボタンには、タイマーに必要なすべての機能を備えた既製のラベルに接続されています。 5分後に開始し、分:秒にフォーマットし、0時になるとタイマーを無効にします。このボタンは、タイマーが開始されると停止/リセット機能としても機能します。

ViewController.h

@interface ViewController : UIViewController{ 

    IBOutlet UILabel *timerDisplay; 
    NSTimer *timer; 
    bool timerActive; 
    int MainInt; 
    int minutes; 
    int seconds; 

} 

@property (nonatomic, retain) UILabel *timerDisplay; 

-(IBAction)start:(id)sender; 
-(void)countdown; 
-(void)timerStop; 
-(void)timeFormat; 

@end 

ViewController.m

@implementation ViewController 

@synthesize timerDisplay; 

-(void)timeFormat{ 
    seconds = MainInt % 60; 
    minutes = (MainInt - seconds)/60; 
    timerDisplay.text = [NSString stringWithFormat:@"%d:%.2d", minutes, seconds]; 
} 

-(void)countdown { 
    MainInt -= 1; 
    [self timeFormat]; 
    if (MainInt <=0){ 
     timerActive = NO; 
     [self->timer invalidate]; 
     self->timer = nil; 
    } 
} 

-(IBAction)start:(id)sender { 
    MainInt = 300; 
    [self timeFormat]; 
    if(timerActive == NO){ 
     timerActive = YES; 
     self->timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(countdown) userInfo:nil repeats:YES]; 
    } 
    else { 
     timerActive = NO; 
     [self->timer invalidate]; 
     self->timer = nil; 
    } 
} 

すべての任意の助けいただければ幸いです。私は、配列や何かを使って、一度に複数のタイマーを持つことができるという助けが大好きです。大量のタイマーをハードコーディングするのはばかげたことです。

乾杯。

EDIT 2:

私は私のアプリとして動作するように以下のコードを持っている、これは私はそれが何をしたいまさにほとんどです。このコードを除いて、一度に1つのタイマーしか実行できませんが、これは私の問題です。

このコードでは、最新のタップの値をタッチスクリーンに保存しています(座標を使用して画面のどこかにタイマーを置く)。そして、1つのボタンを押すと、実行中のタイマーUILabel)は、以前に保存されたタップの位置に表示されます。完了するまで実行され、次にそれ自体が無効になり、ビューから削除されます。 これは正常に動作します。

元のタイマーが完了する前にもう一度ボタンを押すと、新しい場所に新しいタイマー(UILabel付き)が作成されます。この新しいタイマーは正常に動作しますが、古いタイマーはタイマーリファレンスを失ってしまって終了できないため、削除できません。

ViewController.h:

#import <UIKit/UIKit.h> 

@interface ViewController : UIViewController{ 

    UILabel *timerDisplay; 
    NSTimer *timer; 
    CGPoint startPoint; 
    int MainInt; 

} 

@property CGPoint startPoint; 

-(IBAction)startTimer:(id)sender; 
-(void)countdown; 
-(void)timeFormat; 
-(void)start; 

@end 

ViewController.m:

@implementation ViewController 

@synthesize startPoint; 

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 
    UITouch *theTouch = [touches anyObject]; 
    startPoint = [theTouch locationInView:self.view]; 
} 

-(IBAction)startTimer:(id)sender { 

    timerDisplay = [[UILabel alloc] initWithFrame:CGRectMake(startPoint.x -15, startPoint.y - 15, 50, 50)]; 
    timerDisplay.textAlignment = UITextAlignmentCenter; 
    timerDisplay.text = [NSString stringWithFormat:@"%i", MainInt]; 
    timerDisplay.backgroundColor = [UIColor greenColor]; 
    timerDisplay.textColor = [UIColor whiteColor]; 
    [self.view addSubview:timerDisplay]; 
    [self start]; 

} 

-(void)timeFormat{ 
    int seconds = MainInt % 60; 
    int minutes = (MainInt - seconds)/60; 
    timerDisplay.text = [NSString stringWithFormat:@"%d:%.2d", minutes, seconds]; 
} 

-(void)countdown { 
    MainInt -= 1; 
    [self timeFormat]; 
    if (MainInt <= 0){ 
     [self->timer invalidate]; 
     self->timer = nil; 
     [timerDisplay removeFromSuperview]; 
    } 
} 

-(void)start { 
    MainInt = 5; 
    [self timeFormat]; 
    if(self->timer == nil){ 
     self->timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(countdown) userInfo:nil repeats:YES]; 
    } 
} 

@end 

私は、誰かが新しいタイマーインスタンスのそれぞれを保持し、参照を維持するために新しいクラスを作成する際に私を助けることができる期待していました彼らへ。これを行うためにObjective Cの知識が不足しています。あるいは、私を助けてくれそうな例にリンクすることもできます。

乾杯。

答えて

1

あなたのコードはわかりました。私はインスタンス変数が冗長であると言います。timerActiveは、self->timernilでないかどうかだけを確認できるので冗長です。 secondsおよびminutesは、-timeFormatにローカルにできるだけで、インスタンス変数である必要はありません。

これを複数のタイマーを持つ複数のボタン - ラベルペアに一般化する方法がわからないという問題がありますか?私はあなたが各ボタンラベルのペアのためのコントローラとして機能する新しいクラスを作成することをお勧めします。クラスはNSObjectから派生します。現在のところ、ビューコントローラクラスのインスタンス変数は、この新しいクラスのインスタンス変数ですが、ラベルには必ずIBOutletを使用する必要はありません。 (アウトレットはNIBに接続されていますが、おそらくこれらは動的に作成され、コードで接続されます)。

この新しいクラスのインスタンスは、必要なボタンとラベルのペアごとに割り当てて初期化します。ラベルと開始時刻の値へのポインタを渡します。また、所有しているViewControllerオブジェクトへのポインタを渡すこともできます。これにより、停止したときなどに通知することができます。対応するボタンは、この新しいコントローラをターゲットに設定されます。 ViewControllerは、可変アレイ内のこれらのコントローラのそれぞれを追跡します。 1つで終わると、ラベル、ボタン、コントローラが削除されます。

これは役に立ちますか?

+0

ここにはたくさんの有用な情報があります。私がしようとしていたのは、画面上に視覚的な出力を持つ新しい個別のタイマーの作成を制御するボタンを1つ持つことでした(私はUILabelを使って考えました)。私はこれを何回も行うことができ、タイマーを独自の時間シーケンスの終わりに無効にしたいと考えています。私はObjective-Cでのスキルは非常に限られていると言いましたが、他の言語を学んだので、あなたが言ったことをたくさん理解することができます。もう少し詳しく説明できますか?ありがとう。 – Zocozoro

+0

アクションメソッド '-start:'は、タイマーの起動と停止の両方を行っているようです。これは、タイマーごとに別個のボタンが存在することを示唆しています。 –

+0

はい、それは私のアプリでそれを持っていることを計画していませんが、それは二重機能(開始と停止)として機能します。上記のコードは、私のフル・タイマー・クラス(私がタイマーについて学んでいる間に書いたものです)のようなものでした。投稿する前に削除するのを忘れました。混乱をおかけして申し訳ありません。 – Zocozoro

関連する問題