Search code examples
swiftuitableviewtimeruilabelnsattributedstring

UILabel Will Not Update with Timer


I tried to use this code to update the time of a uilabel of a custom cell every time the time changes by a minute.

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(true)
    timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { [weak self] _ in
        if let s = self, let tableView = s.tableView, let indexPaths = tableView.indexPathsForVisibleRows {
            for indexPath in indexPaths {
                guard let cell = tableView.dequeueReusableCell(withIdentifier: "PersonCell", for: indexPath) as? PersonCell else { return }
                let person = s.people[indexPath.section]
                cell.time.attributedText = dateIn(timeZone: person.timeZone)
            }
        }
    })
}

This is the dateIn function to return the current time as an NSAttributedString:

func dateIn(timeZone: TimeZone) -> NSMutableAttributedString {
let dateFormatter: DateFormatter = DateFormatter()
var now: Date {
    return Date()
}
// The styles of the dateformatter are configured to show only the time
dateFormatter.dateStyle = .none
dateFormatter.timeStyle = .short
dateFormatter.timeZone = timeZone

// Returns time in chosenTimeZone as a string
let date = dateFormatter.string(from: now)

// The AM/PM is attributed so it can have a smaller font size than the time
let attributedTime = NSMutableAttributedString(string: "\(removeAmPm(from: date))")
let attributedAmPm = amPmAttributed(from: date)
attributedTime.append(attributedAmPm)

    return attributedTime
}

Time is a UILabel that is part of the PersonCell class. For some reason, the contents of the UILabel won't get updated when the time changes, although the value of dateIn(timeZone: person.timeZone) does change (I checked it with a print statement). I looked all over the internet, but couldn't find a solution that worked other than using reloadData(), which I'm not sure would be good for memory and speed.


Solution

  • You have to call another function to change the value in the wanted cell.

    Use this

    let cell = tableView.cellForRow(at: indexPath)

    In your current implementation cell is just a locally created variable. This is not a cell you want.