UIRefreshControl - beginRefreshing not working when UITableViewController is inside UINavigationController UIRefreshControl - beginRefreshing not working when UITableViewController is inside UINavigationController ios ios

UIRefreshControl - beginRefreshing not working when UITableViewController is inside UINavigationController


It seems that if you start refreshing programmatically, you have to scroll the table view yourself, say, by changing contentoffset

[self.tableView setContentOffset:CGPointMake(0, -self.refreshControl.frame.size.height) animated:YES];

I would guess the reason for this is that it could be undesirable to scroll to the refresh control when user is in the middle/bottom of the table view?

Swift 2.2 version by @muhasturk

self.tableView.setContentOffset(CGPoint(x: 0, y: -refreshControl.frame.size.height), animated: true)

In a nutshell, to keep this portable add this extension

UIRefreshControl+ProgramaticallyBeginRefresh.swift

extension UIRefreshControl {    func programaticallyBeginRefreshing(in tableView: UITableView) {        beginRefreshing()        let offsetPoint = CGPoint.init(x: 0, y: -frame.size.height)        tableView.setContentOffset(offsetPoint, animated: true)            }}


UITableViewController has automaticallyAdjustsScrollViewInsets property after iOS 7. The table view may already have contentOffset, usually (0, -64).

So the right way to show refreshControl after programmingly begin refreshing is adding refreshControl's height to existing contentOffset.

 [self.refreshControl beginRefreshing]; [self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated:YES];


Here's a Swift extension using the strategies described above.

extension UIRefreshControl {    func beginRefreshingManually() {        if let scrollView = superview as? UIScrollView {            scrollView.setContentOffset(CGPoint(x: 0, y: scrollView.contentOffset.y - frame.height), animated: true)        }        beginRefreshing()    }}