2017-07-27 3 views
0

Ich benutze einen Timer um einen Int zu inkrementieren und mit einem Knopfdruck notiere ich die aktuelle Nummer in einem Array. Ich habe auch eine TableView, um den Inhalt des Arrays anzuzeigen. Alles funktioniert gut, außer dass wenn ich das TableView ergreife und es sogar ein wenig zum Scrollen bewege, der Timer hängen bleibt, bis ich das TableView loslasse.Swift 3.2 - Timer() mit TableView

Wie kann ich den Timer laufen lassen, egal was ich mit dem TableView mache?

Hier ist meine ViewController.swift:

import UIKit 
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 

    @IBOutlet var myTableView: UITableView! 

    var timer = Timer() 

    var isTimerOn = false 

    var counter = 0 

    var samples: [Int] = [] 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     myTableView.dataSource = self 
     myTableView.delegate = self 
    } 



    @IBAction func startStopButton(_ sender: Any) { 
     switch isTimerOn { 
     case true: 
      timer.invalidate() 
      isTimerOn = false 
     case false: 
      timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {_ in 
       self.counter += 1 
       print(self.counter) 
      } 
      isTimerOn = true 
     } 

    } 

    @IBAction func recordButton(_ sender: Any) { 
     samples.insert(counter, at: 0) 
     myTableView.reloadData() 
    } 
} 
extension ViewController { 
    func numberOfSections(in tableView: UITableView) -> Int { 
     return 1 
    } 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return samples.count 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! MyCell 

     cell.number = samples[indexPath.row] 

     return cell 
    } 
} 

Wenn Sie es möchten, können Sie das gesamte Projekt siehe: https://github.com/Fr3qu3ntFly3r/TimerTest

Ihnen im Voraus für die Hilfe danken.

+0

Check Seite https://stackoverflow.com/questions/29204229/countdown-timer-on-uitableviewcell-scrolling-laggy-issue-of -geeignete Ansicht – Rex

Antwort

0

Es ist passiert, verwenden Sie die Klassenmethode scheduledTimer(timeInterval:invocation:repeats:) oder scheduledTimer(timeInterval:target:selector:userInfo:repeats:), um den Zeitgeber zu erstellen und ihn im Standardmodus auf der aktuellen Laufschleife zu planen.

Wenn Sie in der UIScrollview- oder UITabellenansicht blättern, wird die Ausführungsschleife im Hauptthread auf UITrackingRunLoopMode umgeschaltet und Aufgaben ausgeführt, die sich in diesem Modus befinden. Das ist, warum Ihre Aufgabe in Standardlaufschleife unabhängig ist.

Dann loslassen Sie die Tabellenansicht, die Run-Loop-Schalter in den Standardmodus, der Timer funktioniert wieder gut.

Das Hinzufügen Ihres Timers zu RunLoop mit commonModes löst dieses Problem.

RunLoop.current.add(timer, forMode: .commonModes)

.commonModes) ist eine konfigurierbare Gruppe von häufig verwendeten Modi. Wenn einer Eingangsquelle dieser Modus zugeordnet wird, wird sie auch jedem Modus in der Gruppe zugeordnet.

Hope this könnte Ihnen helfen :)

Weitere Informationen:

Run Loops Docs

+0

Es funktioniert perfekt. Danke vielmals! –

0

auf, was falsch ist, ist

var timer = Timer() 

An dieser Stelle erstellen Sie eine völlig nutzlos Timer-Objekt Was Sie tun sollten, ist, nie einen Timer zu haben, der nicht wirklich geplant ist. Also:

var timer = Timer? 
// No variable isTimerOn 

Dann in der startStopButton:

if let timer = self.timer { 
    timer.invalidate() 
    self.timer = nil 
} else { 
    self.timer = Timer.scheduledTimer (...) 
} 
+0

Danke für die Bemerkung. Behoben: D –