I have a UITableView that is constrained to the superview. So the first cell is at the top of the superview. Which means on the iPhone X that first cell bleeds under the notch, and into the status bar area. Which is exactly right. I want the cell to bleed under the notch and into the status bar area, which is the current result.
Problem is, I also want a refresh control on that table view, so that the user can pull to refresh the content. BUT when you pull to refresh on the iPhone X, the refresh control is cut off by the notch. I don't want the refresh control to be cut off by the notch.
So basically what I want to do is have the table view constrained to the superview, but have the refresh control constrained to the safe area.
I have looked through and it doesn't look like Apple provides many properties or methods to customize the behavior of the the refresh control.
I've considered using some type of custom solution, but every custom solution I have thought of loses all of the prebuilt physics of the refresh control and table view scrolling and such. There is so much behind the scenes logic and I really don't want to sacrifice the feeling of the pull to refresh and how that feels to the user since it's become such a common action in iOS.
Any ideas on how to have the first cell bleed under the notch (constrained to superview) but ensure the refresh control doesn’t get cut off by the notch (constrained to safe area)?
I have also attached screenshots below of how the cells bleed into the status bar, and how the refresh control is cut off by the notch.
EDIT: I have also published a sample project to GitHub here.
But the basic code related to the refresh control is below.
private lazy var refreshControl = UIRefreshControl()
override func viewDidLoad() {
super.viewDidLoad()
refreshControl.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)
tableView.refreshControl = refreshControl
}
@objc func handleRefresh() {
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
self.refreshControl.endRefreshing()
}
}
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