class ExampleViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { // assuming we've added a UITableView as a subview // to our UIViewController in Storyboard and connected it @IBOutlet var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self tableView.delegate = self // instantiate a UIRefreshControl let refreshControl = UIRefreshControl() // assign its target action refreshControl.addTarget(self, action: #selector(doRefresh(_:)), for: .valueChanged) // assign it to the tableView's .refreshControl property tableView.refreshControl = refreshControl } @objc func doRefresh(_ sender: Any?) -> Void { // do what we want for refreshing... // here, we delay for 1-second to simulate getting new data DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: { // get a reference to the Refresh Control that called this func guard let rc = sender as? UIRefreshControl else { return } // done refreshing rc.endRefreshing() }) } // all the other normal tableView stuff // ... }