1

ここに私の問題があります:私はセルの束を持つテーブルビューを持っています。Core Data は、NSFetchedResultsController を使用して Task オブジェクトをセルに読み込みます。今私はそれを持っているので、各セルには DetailViewController があり、次のように辞書に格納されています。

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    DetailViewController *detailVC;
    if (![self.detailViewsDictionary.allKeys containsObject:@(indexPath.row)]){
        detailVC = [[DetailViewController alloc]initWithNibName:@"DetailViewController" bundle:nil];
        [self.detailViewsDictionary setObject:detailVC forKey:@(indexPath.row)];
    }else{
        detailVC = self.detailViewsDictionary[@(indexPath.row)];
    }
        Tasks *task = [[self fetchedResultsController] objectAtIndexPath:indexPath];
        detailVC.testTask = task;
        [[self navigationController] pushViewController:detailVC animated:YES];
}

各 DetailViewController には、テーブルビュー内の任意のインデックス パスにあるセルに相関する Task オブジェクトから時間間隔を取得するタイマー プロパティがあります。詳細ビューコントローラーのコードは次のとおりです。

- (void)viewDidLoad {
    [super viewDidLoad];
    [NSThread detachNewThreadSelector:@selector(startTimer:) toTarget:self withObject:nil];
}
-(IBAction)startTimer:(id)sender{
//default value of showButtonValue when first loaded is 1
    if (testTask.showButtonValue == 1) {
        [startButton setTitle:@"Start" forState:UIControlStateNormal];
        timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
        testTask.showButtonValue = 3;
    } else if (testTask.showButtonValue == 2) {
        [startButton setTitle:@"Resume" forState:UIControlStateNormal];
        [timer invalidate];
        timer = nil;
        testTask.showButtonValue = 3;
    } else if (testTask.showButtonValue == 3){
        [startButton setTitle:@"Pause" forState:UIControlStateNormal];
        timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
        testTask.showButtonValue = 2;
    }
}
-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    nameTextField.text = testTask.taskName;
    [timerLabel setFont:[UIFont fontWithName:@"Arial" size:60]];
    NSUInteger seconds = (NSUInteger)round(testTask.timeInterval);
    NSString *string = [NSString stringWithFormat:@"%02u:%02u:%02u",
                        seconds / 3600, (seconds / 60) % 60, seconds % 60];
    timerLabel.text = string;
    [[self navigationItem] setTitle:[testTask taskName]];

    [timerLabel setNeedsDisplay];
    [self.view setNeedsDisplay];
}
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    testTask.taskName = nameTextField.text;
}
-(void)timerAction:(NSTimer *)t
{
    if(testTask.timeInterval == 0)
    {
        if (self.timer)
        {
            [self timerExpired];
            [self.timer invalidate];
            self.timer = nil;
        }
    }
    else
    {
        testTask.timeInterval--;
    }
    NSUInteger seconds = (NSUInteger)round(testTask.timeInterval);
    NSString *string = [NSString stringWithFormat:@"%02u:%02u:%02u",
                        seconds / 3600, (seconds / 60) % 60, seconds % 60];
    timerLabel.text = string;
    NSLog(@"%f", testTask.timeInterval);
}

詳細View Controllerが現在画面上にあるかどうかに関係なく、タイマーは継続することが想定されています。初めてセルをタップし、詳細ビューコントローラーに移動してタイマーを開始し、テーブルビューに戻ると、問題はなく、カウントダウンが続行されます。問題は、セルをもう一度タップすると、別のタイマーが作成されるため、時間が 2 倍速く減少することです。それだけでなく、残り時間を表示する文字列は ViewWillAppear では更新されず、timerAction が最初に呼び出されたときにのみ更新されます。

たくさんの問題があります。本当に助けていただければ幸いです。

4

2 に答える 2

1

他の質問 (詳細ビュー コントローラーごとに 1 つのタイマー)への回答で提供した didSelectRowAtIndexPath のコードは、戻るボタンを押したときにコントローラーの割り当てが解除されるのを防ぎます。これは、詳細ビュー コントローラーへの参照をディクショナリに保持することによって行われます。辞書を初期化するのを忘れたため、機能していないと思います。つまり、nilです。

于 2013-07-31T05:46:50.043 に答える