Fix scroll-to-top sometimes not scrolling all the way to the top

This commit is contained in:
Shadowfacts 2020-05-10 11:04:49 -04:00
parent 4fdafa893e
commit 6d8c5f632c
Signed by untrusted user: shadowfacts
GPG Key ID: 94A5AB95422746E5
2 changed files with 14 additions and 12 deletions

View File

@ -109,8 +109,9 @@ class TimelineTableViewController: EnhancedTableViewController {
// MARK: - Table view delegate // MARK: - Table view delegate
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// don't remove rows when jumping to the top, otherwise jumping back down might try to show removed rows
// when scrolling upwards, decrement reference counts for old statuses, if necessary // when scrolling upwards, decrement reference counts for old statuses, if necessary
if scrollViewDirection < 0 { if !isCurrentlyScrollingToTop, scrollViewDirection < 0 {
if indexPath.section <= timelineSegments.count - 2 { if indexPath.section <= timelineSegments.count - 2 {
// decrement ref counts for all sections below the section below the current section // decrement ref counts for all sections below the section below the current section
// (e.g., there exist sections 0, 1, 2 and we're currently scrolling upwards in section 0, we want to remove section 2) // (e.g., there exist sections 0, 1, 2 and we're currently scrolling upwards in section 0, we want to remove section 2)

View File

@ -11,25 +11,26 @@ import SafariServices
class EnhancedTableViewController: UITableViewController { class EnhancedTableViewController: UITableViewController {
var prevScrollToTopOffset: CGPoint? = nil private var prevScrollToTopOffset: CGPoint? = nil
private(set) var isCurrentlyScrollingToTop = false
private var topOffset: CGPoint {
// when scrolled to top, the content offset is negative the height of the UI above the scroll view (i.e. the nav and status bars)
let windowScene = view.window!.windowScene!
let barOffset = -1 * (navigationController!.navigationBar.frame.height + windowScene.statusBarManager!.statusBarFrame.height)
// add one so it's not technically all the way at the top, and scrollViewWShouldScrollToTop is still called to trigger undo
return CGPoint(x: 0, y: barOffset + 1)
}
override func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool { override func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
if let offset = prevScrollToTopOffset { if let offset = prevScrollToTopOffset {
tableView.setContentOffset(offset, animated: true) tableView.setContentOffset(offset, animated: true)
prevScrollToTopOffset = nil prevScrollToTopOffset = nil
return false
} else { } else {
prevScrollToTopOffset = tableView.contentOffset prevScrollToTopOffset = tableView.contentOffset
tableView.setContentOffset(topOffset, animated: true) isCurrentlyScrollingToTop = true
return true
} }
return false }
override func scrollViewDidScrollToTop(_ scrollView: UIScrollView) {
isCurrentlyScrollingToTop = false
// add one so it's not technically scrolled all the way to the top,
// otherwise there's no way of detecting a status bar press to scroll back down
tableView.contentOffset.y -= 0.5
} }
override func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { override func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {