CRAnimation/CRRefresh

Pull to Refresh breaks with iOS13

rscherf opened this issue · 0 comments

It doesn't appear that there is much activity support iOS13/Swift 5, so thought I'd drop a very hacky solution for supporting pull-to-refresh, particularly in a modal.

Since CRRefresh uses tableView.addSubview instead of tableView.refreshControl, the experience gets a bit odd in iOS13, in particular with modal sheets. Pulling down to refresh will actually dismiss the modal, instead of refreshing the tableView. There are some solutions that use isModalInPresentation = true, but that allows for a slight drag of the modal, and no affordance showing that PTR is happening. See this SO thread:

My solution was to fake the RefreshControl, but hide it.

extension UITableView {
  func iOS13RefreshControlHack() {
    if #available(iOS 13.0, *) {
      let refreshControl       = UIRefreshControl()
      refreshControl.tintColor = .clear
      
      self.refreshControl      = refreshControl
      self.refreshControl?.addTarget(self, action: #selector(handleRefreshControl), for: .valueChanged)
    }
  }
  
  @objc func handleRefreshControl() {
    self.refreshControl?.endRefreshing()
  }
}

Then call from your tableView via (or whatever better name you choose):

self.tableView.iOS13RefreshControlHack()

This triggers the modal to behave properly when PTR is requested, but also continues to show the CRRefresh custom spinners/checkmark instead. In addition, you can still dismiss the modal by pulling down from the navigationBar, but the modal does not move when pulling on the table cells.

Hope it helps someone.