Search code examples
swiftuitableviewuinavigationcontrolleruirefreshcontrol

UIRefreshControl renders behind UINavigation w/ Large Titles


I am trying to create a UITableViewController, with a UINavigationBar using large titles.

The trouble I am having is, when using pull to refresh on an empty table view, the loading indicator is behind the text for the large title.

If I pull to refresh a second time it does not have this issue.

I have attached a gif that shows the behaviour.unwanted behaviour

My view controller is very simple at this point

final class FeedSceneViewController: UITableViewController {

  private var loader: FeedLoader?

  convenience init(loader: FeedLoader) {
    self.init()
    self.loader = loader
  }

  override func viewDidLoad() {
    super.viewDidLoad()

    tableView.refreshControl = .init()
    load()

    configureTableView()
    configureUI()
  }

  func load() {
    tableView.refreshControl?.set(isRefreshing: true)
    loader?.load(then: { [weak self] _ in self?.refreshControl?.set(isRefreshing: false) })
  }

}

private extension FeedSceneViewController {

  func configureTableView() {
    tableView.backgroundColor = .usingHex("fafafa")
    tableView.tableFooterView = .init()
  }

  func configureUI() {
    navigationController?.navigationBar.prefersLargeTitles = true
    navigationItem.title = "Latest content"
  }
}


Solution

  • It looks like you are setting the refresh control after the large navigation has been configured.

    Try changing the order to something like this -

      override func viewDidLoad() {
        super.viewDidLoad()
    
        load()
    
        configureTableView()
        configureUI()
      }
    .......
      func configureTableView() {
        tableView.backgroundColor = .usingHex("fafafa")
        tableView.tableFooterView = .init()
        tableView.contentInsetAdjustmentBehavior = .always
        tableView.refreshControl = .init()
      }
    
      func configureUI() {
        navigationController?.navigationBar.prefersLargeTitles = true
        navigationItem.title = "Latest content"
      }