1

I have a table view inside a container. When a user swipes down to refresh I notice that the cells instantly pop back to the top. It looks very buggy.

func setupRefresh() {
    //        refreshControl.attributedTitle = NSAttributedString(string: "")
    refreshControl.addTarget(self, action: #selector(refresh(_:)), for: UIControl.Event.valueChanged)
    tableView.insertSubview(refreshControl, at: 0)
    //tableView.addSubview(refreshControl) // not required when using UITableViewController
}

@objc func refresh(_ sender:AnyObject) {
    // Code to refresh table view
    print("Refreshing...")
    tableView.isScrollEnabled = false
    array.removeAll()
    items = 0
    number = 0
    getRecentNotifs(limit: 10)
    //        refreshControl.endRefreshing()
    //        tableView.isScrollEnabled = true
    //        tableView.isUserInteractionEnabled = true
}

Then within my fetch method, I do this. I also tried doing this inside of the refresh and that failed, yielding the same results

dispatchGroup.notify(queue: .main, execute: {
    if true {
        if !self.tableView.isScrollEnabled {
            self.refreshControl.endRefreshing()
            self.tableView.isScrollEnabled = true
        }

        self.tableView.reloadData()
    }
})

I have looked here and many more places with no success.

A very bad fix to this could be:

 ...
Timer.scheduledTimer(timeInterval: 0.8, target: self, selector: #selector(self.delayedAction), userInfo: nil, repeats: false)
}

@objc func delayedAction() {
    refreshControl.endRefreshing()
}
inexcitus
  • 2,471
  • 2
  • 26
  • 41

1 Answers1

1

Move the refreshControl.endRefreshing() into the completion handler of the function you are getting the data from.

Example:

func getRecentNotifs(limit: Int) {

     // Get Data ...

     Network.getData(limit: limit) { (data, error) in   // Completion Block

          // Update Table View
          self.tableView.reloadData()

          // End Refresh Control
          self.refreshControl.endRefreshing()
          self.activityIndicatorView.stopAnimating()

     })

}

You were calling refreshControl.endRefreshing() in the refresh control's target method, so it was ending right away.

Nathan
  • 949
  • 8
  • 19
  • Then I get: Argument of '#selector' does not refer to an '@objc' method, property, or initializer on: refreshControl.addTarget(self, action: #selector(refresh()), for: UIControl.Event.valueChanged) –  Jul 18 '19 at 07:04
  • 1
    @Outsider you don't put the parenthesis at the end of `refresh` in the `#selector(refresh)`. Change to `refreshControl.addTarget(self, action: #selector(refresh), for: .valueChanged)` – Nathan Jul 18 '19 at 07:16