Search code examples
iosswiftuitableviewnotificationcenter

TableView fail to reload after `tableView.reloadData()` is called


I have two tabs. The first tab contains a UITableViewController, with its tableView's cells containing some words. The second tab is for settings, containing a tableView, with a cell for setting font size. After the user taps the cell, the user will enter the interface for changing the font size. When the user presses the "save" button, (a button in the editing-font-size interface to save the adjusted font size.) the top view controller is popped back to the original tableView for settings.

I use observers to post notification when the save button is pressed, and the respective observers will update its view. I added an observer in the tableView for settings, and it works. When the top view controller for editing font size is popped, the original tableView is presented with adjusted font size.

However, when I added an observer in the UITableViewController in the first tab, the tableView is not reloaded. I have added a print message in the selector method of NotificationCenter.default.addObserver(_:selector:name:object:) and confirm that the selector method is called. The selector method looks like this:

@objc func reloadTableView() {
    print("The method is called.")
    tableView.reloadData()
}

The code that I use the font size in the first tab's tableView cell:

labelOne.font = UIFont(descriptor: fontDescriptor, size: fontSizeForLabelOne)
labelTwo.font = UIFont(descriptor: fontDescriptor, size: fontSizeForLabelTwo)

It seems very confusing to me, since the method to reload tableView is called, yet the table view is not reloaded? And since the font size is changed, when I scroll the tableView the new cells are randomly in the old font size or adjusted font size.

I have also tried it with labels, and it works on them even if it is in a different tab. In other words, I think the problem only occurs for tableView.

On the other hand, since it works for the table view in setting tab, am I right to say that tableView can only be reloaded when tableView.reloadData() is called when the tableView is about to be presented? If tableView is not presented and tableView.reloadData() is called, nothing will happen, and everything remains the same?

In short, is there anyway to ensure that tableView is reloaded when I change my font size?


Solution

  • Eventually I found a solution by, since my view controllers are managed by navigation controller, I pop the view controller and load it again as the alternative to reload the table view. Namely,

    @objc func reloadTableView() {
        navigationController.popViewController(animated: false)
        navigationController.pushViewController(theViewController, animated: false)
    }
    

    The only downside of this is that the view controller will be reset to its initial state, i.e. if the table view in the view controller is scrolled down, when the user goes back to the view controller from setting, the table view is reset to its top position and does not show where it was scrolled to.