ストップウォッチアプリ04〜完成

前回までのストップウォッチアプリでは、一度stopボタンを押したあとにもう一度startを押しても、カウントの再開ができていませんでした。

その改善を行いました。

ポイント

  1. stopボタン押下時のラベルの値を文字列型からfloat型に変換して保持しておく
  2. 再度startボタンが押された場合は、保持しておいたfloat変数を足したものをラベルに表示する

ソース

.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize lbl;

NSDate *stdate;
BOOL timeflg=FALSE;
BOOL flg_stopdown=FALSE;
float fTmp1, fTmp2;
NSString *strTmp1, *strTmp2;


- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // ラベルの初期化
    self.lbl.text = @"0.000";
    
    //「onTimerという処理を、0.001秒間隔で繰り返し実行する」
    timer = [NSTimer scheduledTimerWithTimeInterval:(0.001)
                                             target:self selector:@selector(onTimer:)
                                           userInfo:nil repeats:YES];

}

- (void)viewDidUnload
{
    [self setLbl:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    [timer invalidate];//★タイマー解放忘れずに
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (void)onTimer:(NSTimer*)timer {
    // グローバルなフラグがTRUEのとき、
    // つまり、startボタンが押されたら常に真となり下記処理が実行される
    if(timeflg){
        NSDate *now = [NSDate date];//現在時刻
        //NSDate *tmp;//時刻計算用
        if(flg_stopdown){
            
            // いちどString型に入れる
            strTmp2 = [NSString stringWithFormat:@"%.3f",
                             [now timeIntervalSinceDate:stdate]];
            
            // 計算用にfloatに変換
            fTmp2 = [strTmp2 floatValue];
            
            float fTmp3;
            
            // stop押下時のラベルの時間を足す
            fTmp3 = fTmp1 + fTmp2;
            
            self.lbl.text = [NSString stringWithFormat:@"%.3f", fTmp3];
            
            
        }
        else{
            self.lbl.text = [NSString stringWithFormat:@"%.3f",
                             [now timeIntervalSinceDate:stdate]];
        }
    }
}

- (IBAction)clear_down:(id)sender {
    flg_stopdown = FALSE;
    timeflg = FALSE;
    self.lbl.text = @"0.000";
}

- (IBAction)stop_down:(id)sender {
    if(timeflg){
        flg_stopdown = TRUE;
        
        // いったんstring型に入れる
        strTmp1 = self.lbl.text;
        
        // 計算用にfloatに変換
        fTmp1 = [strTmp1 floatValue];
        
    }
    timeflg = FALSE;
}

- (IBAction)start_down:(id)sender {
    if(timeflg == FALSE){
        timeflg = TRUE;
        stdate = [NSDate date];
        //[stdate retain];// unavailableエラーのためコメントアウト
    }
}
@end

ストップウォッチアプリ作成を終えて

値の保持と加算にかなり苦しみました。
stopを押したときの時間(NSDate)を加算しなければいけないと考えていたためです。
NSDateで調べても、60秒後とか1日後といった加算はありましたが、NSDate同士の加算がどうしても見つからず、途方にくれていました。
今回は秒単位しか使用しないということで、なかば無理やり数値型に変換してその加算を行うという暴挙に出てしまいました。
「ストップウォッチ アプリ」などのキーワードで調べたのですが、値の保持と加算について書いてある記事を見つけることができず、このような結果になりました。
とりあえず見かけ上はstart, stop, clear, 再startというストップウォッチアプリの基本的な機能をそなえたアプリができました。
タイマーは自分にとってのある種の鬼門になりました。。。

加算以外のボタンを押したときの細かいフラグの変化も地味に気をつかった部分なので、作成する際は注意するとよいとおもいます。

参考

ラベルの文字列をfloatに変換したり、その逆を行う際にお世話になった記事です。
初心者が進めるiphoneアプリ開発 文字列を数値などに変換する(NSString)