How to stop timer lag when scrolling?

I am working with Swift 3 and have a Timer object running which is counting for the duration of a specific task in a list. When that task completes, it moves onto the next task.


The tasks are shown in a UITableView which the user can scroll through whilst the top task is being processed. I have noticed that when scrollling through the table, this seems to impact the firing of the timer (interval is 1 sec) and over the course of working on a number of tasks it is losing time. At the start, I calculate how long the overall list of tasks will take to finish and show this as a target completion time. If I don't do any scrolling, the tasks complete exactly on time. If I scroll about, the tasks finish late.


I have been looking online for solutions and there seems to be examples of this in Swift 2 which uses NSTimers and NSRunLoop to help get around this. I tried something similar in Swift 3 with RunLoop but doesn't seem to help.


Any pointers?


Thanks,

Rob.

Post not yet marked as solved Up vote post of Robmeister Down vote post of Robmeister
4.5k views

Replies

The most common cause of problems like this is scheduling the timer in the default run loop mode. When the UI frameworks are tracking user activity (like scrolling) they typically don’t run the default run loop mode, but instead run some UI tracking mode. Thus, timers scheduled in the default mode don’t run.

If you want a timer to run in that mode, you should schedule it in the common modes. For example:

let t = Timer(timeInterval: 1.0, repeats: true) { _ in
    NSLog("ping")
}
RunLoop.current.add(t, forMode: .commonModes)

The common modes are a pseudo mode that encompasses… well… all common modes, that is, the default run loop mode and modes used by the UI frameworks for scrolling and so on.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
  • I’m scratching my head that the RunLoop.current.add(_ : forMode:) method won’t compile. Swiftui. Foundation. Combine. They’re all imported into the file. The error says “no exact match to instant method” any insight?

  • @jessielinden It appears to be in Foundation. Maybe you ran into a compiler bug

  • .commonModes was renamed to .common

Add a Comment