2017-07-27 7 views
0

私はTimerを使ってIntをインクリメントしています。ボタンを押すと、現在の数値が配列に記録されます。また、配列の内容を表示するTableViewもあります。私がTableViewをつかんでそれを少しでもスクロールすると、TableViewを解放するまでタイマーがハングするという点を除いて、すべてうまく動作します。Swift 3.2 - TableViewを使ったTimer()

私はTableViewに何をしていても、タイマーを実行し続けることができますか?ここで

私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 
    } 
} 

あなたがそれを必要とする場合は、上のプロジェクト全体を見ることができます: https://github.com/Fr3qu3ntFly3r/TimerTest

事前に助けをいただき、ありがとうございます。

+0

このページをチェックしhttps://stackoverflow.com/questions/29204229/countdown-timer-on-uitableviewcell-scrolling-laggy-issue-of -uitableview – Rex

答えて

0

scheduledTimer(timeInterval:invocation:repeats:)またはscheduledTimer(timeInterval:target:selector:userInfo:repeats:)クラスメソッドを使用して、タイマーを作成し、デフォルトモードで現在の実行ループでスケジュールすることが原因でした。

UIScrollviewまたはUITableviewをスクロールすると、メインスレッドの実行ループがUITrackingRunLoopModeに切り替えられ、このモードのタスクが実行されます。 そのため、デフォルトの実行ループ内のタスクは関係なくなります。

次に、実行ビューのループをデフォルトモードに切り替えると、タイマーは再び正常に動作します。

CommonModeでRunLoopにタイマーを追加すると、この問題は解決します。

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

.commonModes)一般的に使用されるモードの設定可能な基です。入力ソースをこのモードに関連付けると、グループ内の各モードにも関連付けられます。これはあなたを助けることができる:)

希望はこちらをご覧ください:間違っている事に

Run Loops Docs

+0

それは完全に動作します。どうもありがとう! –

0

は、この時点で

var timer = Timer() 

で、あなたは完全に役に立たないを作成していますTimerオブジェクト。あなたがすべきことは、実際にスケジュールされていないタイマーを決して持っていないことです。だから、:startStopButtonで次に

var timer = Timer? 
// No variable isTimerOn 

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

ありがとうございました。それを修正しました:D –

関連する問題