diff --git a/iOS/MasterTimeline/MasterTimelineViewController.swift b/iOS/MasterTimeline/MasterTimelineViewController.swift index bf23f7dd1..16e6d9cc1 100644 --- a/iOS/MasterTimeline/MasterTimelineViewController.swift +++ b/iOS/MasterTimeline/MasterTimelineViewController.swift @@ -25,6 +25,7 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner weak var coordinator: SceneCoordinator! var undoableCommands = [UndoableCommand]() + let scrollPositionQueue = CoalescingQueue(name: "Scroll Position", interval: 0.3, maxInterval: 1.0) private let keyboardManager = KeyboardManager(type: .timeline) override var keyCommands: [UIKeyCommand]? { @@ -73,6 +74,13 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner override func viewWillAppear(_ animated: Bool) { applyChanges(animate: false) + + // Restore the scroll position if we have one stored + if let restoreIndexPath = coordinator.timelineMiddleIndexPath { + tableView.scrollToRow(at: restoreIndexPath, at: .middle, animated: false) + } + + // Hide the search controller if we don't have any rows if dataSource.snapshot().numberOfItems < 1 { navigationItem.searchController?.isActive = false } @@ -288,6 +296,10 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner coordinator.selectArticle(article, animated: true) } + override func scrollViewDidScroll(_ scrollView: UIScrollView) { + scrollPositionQueue.add(self, #selector(scrollPositionDidChange)) + } + // MARK: Notifications @objc dynamic func unreadCountDidChange(_ notification: Notification) { @@ -366,6 +378,10 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner titleView?.label.text = coordinator.timelineName } + @objc func scrollPositionDidChange() { + coordinator.timelineMiddleIndexPath = tableView.middleVisibleRow() + } + // MARK: Reloading func queueReloadAvailableCells() { diff --git a/iOS/SceneCoordinator.swift b/iOS/SceneCoordinator.swift index b57d60ed3..b9c60d2ef 100644 --- a/iOS/SceneCoordinator.swift +++ b/iOS/SceneCoordinator.swift @@ -135,6 +135,8 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider { var timelineFetcher: ArticleFetcher? { didSet { + timelineMiddleIndexPath = nil + if timelineFetcher is Feed { showFeedNames = false } else { @@ -153,6 +155,8 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider { } } + var timelineMiddleIndexPath: IndexPath? + private(set) var showFeedNames = false private(set) var showIcons = false @@ -529,7 +533,7 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider { } func selectFeed(_ indexPath: IndexPath?, animated: Bool = false) { - guard indexPath != currentFeedIndexPath else { return } + guard indexPath != currentFeedIndexPath else { return } selectArticle(nil) currentFeedIndexPath = indexPath @@ -1589,7 +1593,7 @@ private extension SceneCoordinator { subSplitViewController!.showDetailViewController(navController, sender: self) masterFeedViewController.restoreSelectionIfNecessary(adjustScroll: true) - masterTimelineViewController!.restoreSelectionIfNecessary(adjustScroll: true) + masterTimelineViewController!.restoreSelectionIfNecessary(adjustScroll: false) // We made sure this was there above when we called configureDoubleSplit return subSplitViewController!