iOS UITableView Offset Refresh Control
You can take benefits for underlaying UIScrollView
. With your github example you got everything you need there, so if you extend it with:
extension ViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y < 0 {
topConstraint.constant = -scrollView.contentOffset.y/2
} else {
topConstraint.constant = 0
}
}
}
What react every time contentOffset
starts to be lower than 0
and make your tableView
moved to bottom and whenever is closed or scrolling down it will be set to default value - in your case 0
.
That way you will endup with smooth animation related to dragging force/distance as below
The solution is easy, you can set bounds of your refresh control in viewDidLoad. Use y offset value you need (50 for example)
refreshControl.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)
refreshControl.bounds = CGRect(x: refreshControl.bounds.origin.x,
y: 50,
width: refreshControl.bounds.size.width,
height: refreshControl.bounds.size.height)
tableView.refreshControl = refreshControl
UPDATE:
You can add content inset at refresh beginning, and bring it back at the end.
override func viewDidLoad() {
super.viewDidLoad()
refreshControl.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)
refreshControl.bounds = CGRect(x: refreshControl.bounds.origin.x,
y: -100,
width: refreshControl.bounds.size.width,
height: refreshControl.bounds.size.height);
tableView.refreshControl = refreshControl
}
@objc func handleRefresh() {
self.tableView.contentInset = UIEdgeInsets(top: 200, left: 0, bottom: 0, right: 0)
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
self.refreshControl.endRefreshing()
self.tableView.contentInset = UIEdgeInsets.zero
self.tableView.setContentOffset(.zero, animated: true)
}
}