Search code examples
swiftuitableviewuikit

Updating information in a TableView using a Timer


I have a UITableView that displays a list of cities and the current time in those cities, which I update using a Timer.

I am starting initializing the time like this:

clockTimer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { [self] t in
    let myTime = Date().formatted(date: .omitted, time: .standard)

    for i in 0 ..< cities.count {
        let cityGMTDiff = cities[i].gmtDiff
        let overallGMTDiff = cityGMTDiff - myGMTDiff
        let cityTime = Date().addingTimeInterval(Double(overallGMTDiff) * 3600.0).formatted(date: .omitted, time: .standard)
        cities[i].time = cityTime
    }
    citiesTableView.reloadData()
}

I am also implementing the ability to delete a row of the TableView using with this delegate method:

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        cities.remove(at: indexPath.row)
        citiesTableView.deleteRows(at: [indexPath], with: .automatic)
    }
}

What's happening, though, is that when I try to delete a row the timer updates the TableView, preventing me from completing the delete row operation.

I have tried to invalidate the timer as soon as I select a row, however I suspect that's not the proper way to handle this.


Solution

  • Obviously the issue is the call to reloadData every 0.5 seconds. That prevents very little interaction with the table view.

    There are a few possible solutions that I can think of.

    1. When the timer triggers, get the cells for the visible rows. Iterate the cells and tell each cell to update itself with the current time. This uses much less overhead and it avoids the use of reloadData and allows the user to swipe-to-delete a row.

    2. Do what the standard Clock app does on the World Clock tab. Only allow deletions while in Edit mode. And during Edit mode, you don't show the time which means you don't call reloadData while in Edit mode.