2016-12-22 7 views
0

各セルにラベルが付いたUITableViewがあります。セル上のボタンを押すと、0.01ミリ秒ごとに各セルのラベルを更新する必要があります。それぞれのUITableViewCellでタイマーが実行されているとき、それらは正しくリサイクルされていません。

func tick(label: UILabel) { 
    let timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) { (timer) in 
     // functionality to decide what to put in the label goes here 
     label.text = "some string" 
    } 
} 


// button action 
@IBAction func startButtonPressed(_ sender: UIButton) { 
    let buttonPostion = sender.convert(CGPoint.zero, to: tableView) 

    if let indexPath = tableView.indexPathForRow(at: buttonPostion), let cell = tableView.cellForRow(at: indexPath) as? CustomCell { 
     tick(label: cell.label) 
    } 
} 

問題は、私がUITableViewをスクロールすると、セルが適切にリサイクルされないということです。たとえば、一番上のセルの開始ボタンをクリックすると、タイマーが起動し、ラベルの変更が開始されます。次にスクロールすると、別のセルのラベルも上のセルと同じになりますそのタイマが開始される。

この問題を解決する最善の方法は何ですか?

+0

@Tom Harringtonの答えの代わりに、タイマーをデータソースと結合することをおすすめします。 –

答えて

1

セルが正しく再利用されているようです。セル再利用の考え方は、UITableViewCellのインスタンスが画面からスクロールしたとき、新しいセルがもう一方の端に必要なときに、その正確なインスタンスが再度使用されるということです。セル内でタイマーを開始すると、そのセルは再利用されます。同じオブジェクトであるため、既に実行されている同じタイマーがあります。何らかの状態(たとえば実行中のタイマー)のセルを設計する場合は、セルが再利用されるときにその状態をリセットする必要があります。

セルにタイマを保持する場合は、セルを再利用するときにタイマを停止して再起動する必要があります。セルを再利用するときに実行中のタイマーが存在しないように、テーブルセルクラスのprepareForReuseをオーバーライドすることによってタイマーを停止することができます。それらを再起動するには、セルをデキューするときにタイマーを開始できるように、テーブルビューのデータソースでタイマーを実行しているセルを追跡する必要があります。

関連する問題