Search code examples
iosswiftxcodeuikituirefreshcontrol

UIRefreshControl: table view jumps weirdly


I have a UIRefreshControl inside a table view, and my problem is that when I pull down the table view, there is a certain point where the size change of the refresh control is not animated, but it jumps abruptly to one size to another.

I recreated the behavior in a simple example, this is all the code I have in my View Controller:

class ViewController: UIViewController {
    
    let refreshControl = UIRefreshControl()
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        
        refreshControl.backgroundColor = .blue
        tableView.refreshControl = refreshControl
        tableView.insertSubview(refreshControl, at: 0)
    }
}

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 20
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "testCell", for: indexPath)
        cell.textLabel?.text = "\(indexPath.row)"
        return cell
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        refreshControl.endRefreshing()
    }
}

On the following video you can see that the size change animates smoothly, except for a certain point where it starts jumping: enter image description here


Solution

  • You could do this in swift like:

    var refreshControl = UIRefreshControl()
    
    override func viewDidLoad() {
      super.viewDidLoad()
    
      tableView.delegate = self
      tableView.dataSource = self
    
      refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
      refreshControl.addTarget(self, action: #selector(self.refresh(_:)), for: .valueChanged)
      tableView.addSubview(refreshControl) // not required when using UITableViewController
    }
    
    @objc func refresh(_ sender: AnyObject) {
       // Code to refresh table view  
       refreshControl.endRefreshing() // End Refreshing
    }
    

    You can't endRefreshing() in scrollViewDidEndDecelerating method and update your viewDidLoad() like above.