私のアプリでは、tableViewの各セルに異なるtimeIntervalを持つタイマーを設定し、timerを返すsetTimer関数を作成し、timerを無効にするprepareForReuse関数を作成しました。私はここにcellForRow関数内関数SETTIMERを呼び出すのViewControllerでタイマーが正常に動作しない
class cellForData: UITableViewCell {
@IBOutlet weak var iconImage: UIImageView!
@IBOutlet weak var dataText: UILabel!
var timerArray: Array = [Timer(), Timer(), Timer(), Timer(), Timer(), Timer(), Timer(), Timer(), Timer(), Timer()]
var count: Double = 0
var texts = String()
var countHowMuch = Double()
func setTimer(withInterval: Double, text: String, countTimes: Double) -> Timer {
texts = text
countHowMuch = countTimes
return Timer.scheduledTimer(timeInterval: withInterval, target: self, selector: #selector(handle), userInfo: nil, repeats: true)
}
func handle() {
count += countHowMuch
dataText.text = "\(count) + \(texts)"
}
override func prepareForReuse() {
super.prepareForReuse()
timerArray[timerArray.count - 1].invalidate()
}
}
その
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "secondVCCell") as? cellForData {
cell.timerArray[indexPath.row] = cell.setTimer(withInterval: arrayOfAStruct[indexPath.row].seconds, text: arrayOfAStruct[indexPath.row].text, countTimes: arrayOfAStruct[indexPath.row].countTimes)
RunLoop.main.add(cell.timerArray[indexPath.row], forMode: .commonModes)
return cell
}
return UITableViewCell()
}
のためのコードは、テーブルビューにスクロール細胞は奇妙な振る舞いをするときので、これらの細胞は常に位置を変更し、その後タイマーが動作しないです小道具ええ、私はタイマーが無効化さえしないと思います。セル再利用とセルが同じ位置に留まるたびに、タイマーを無効にする必要があります。ここに私の全体のビューコントローラ
import UIKit
構造体forShowedVC { のvar画像です:UIImage! var text:文字列! var秒:ダブル! var countTimes:Double! }
クラスshowedVC:のUIViewController、UITableViewDataSource、UITableViewDelegate {
@IBOutlet weak var myTableView: UITableView!
var arrayOfAStruct = [forShowedVC]()
override func viewDidLoad() {
super.viewDidLoad()
myTableView.dataSource = self
myTableView.delegate = self
arrayOfAStruct = [forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "a", seconds: 1, countTimes: 3),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "b", seconds: 1, countTimes: 2),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "c", seconds: 1, countTimes: 7),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "d", seconds: 1, countTimes: 12),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "e", seconds: 1, countTimes: 1),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "f", seconds: 1, countTimes: 9),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "g", seconds: 1, countTimes: 13),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "h", seconds: 1, countTimes: 71),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "i", seconds: 1, countTimes: 4),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "j", seconds: 1, countTimes: 6)]
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "secondVCCell") as? cellForData {
cell.timerArray[indexPath.row] = cell.setTimer(withInterval: arrayOfAStruct[indexPath.row].seconds, text: arrayOfAStruct[indexPath.row].text, countTimes: arrayOfAStruct[indexPath.row].countTimes)
RunLoop.main.add(cell.timerArray[indexPath.row], forMode: .commonModes)
return cell
}
return UITableViewCell()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayOfAStruct.count
}
}
に
cell.cellTimer?.invalidate()
への呼び出しを置くことができます。 cellForRowAtをいつも呼び出す回数を指定して、問題の原因となっていることを確認します。 –reloadData()を呼び出すすべてのセルでタイマーを実行するのは悪いことです。セルのタイマーが起動するたびに、テーブルビュー全体をリロードしています。 'reloadRows(at:with:)'を使って、どのセルが変更されたか把握し、それらのセルをリロードするだけでよいのです。 –
すべてを変更してください。 –