Skip to content

Instantly share code, notes, and snippets.

@mttcrsp
Last active February 21, 2021 00:00
Show Gist options
  • Save mttcrsp/53a6fec3a5a16e020aa97926428057c9 to your computer and use it in GitHub Desktop.
Save mttcrsp/53a6fec3a5a16e020aa97926428057c9 to your computer and use it in GitHub Desktop.
Extension that allows programmatic pull to refresh
import UIKit
public extension UITableView {
public func beginRefreshing() {
// Make sure that a refresh control to be shown was actually set on the view
// controller and the it is not already animating. Otherwise there's nothing
// to refresh.
guard let refreshControl = refreshControl, !refreshControl.isRefreshing else {
return
}
// Start the refresh animation
refreshControl.beginRefreshing()
// Make the refresh control send action to all targets as if a user executed
// a pull to refresh manually
refreshControl.sendActions(for: .valueChanged)
// Apply some offset so that the refresh control can actually be seen
let contentOffset = CGPoint(x: 0, y: -refreshControl.frame.height)
setContentOffset(contentOffset, animated: true)
}
public func endRefreshing() {
refreshControl?.endRefreshing()
}
}
// MARK: - Demo
import PlaygroundSupport
extension UITableViewCell {
static var identifier: String {
return String(describing: self.self)
}
}
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
let action = #selector(ViewController.refreshControlDidStart(sender:event:))
refreshControl = UIRefreshControl()
refreshControl?.addTarget(self, action: action, for: .valueChanged)
tableView.register(UITableViewCell.self, forCellReuseIdentifier: UITableViewCell.identifier)
}
func refreshControlDidStart(sender: UIRefreshControl?, event: UIEvent?) {
print(#function)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 100
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: UITableViewCell.identifier, for: indexPath)
cell.textLabel?.text = "SOMETHING"
return cell
}
}
let viewController = ViewController()
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
viewController.tableView.beginRefreshing()
}
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
viewController.tableView.endRefreshing()
}
PlaygroundPage.current.liveView = viewController
@az-oolloow
Copy link

Nice gist, however somehow when I use this code if my refreshControl had a attributedTitle it doesn't show :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment