From 366834e2e45f967305b20243bc1edcb4ab419b61 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Thu, 24 Nov 2022 11:05:56 -0500 Subject: [PATCH] Tweak timeline state restoration to maintain scroll position of center item --- .../Timeline/TimelineViewController.swift | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/Tusker/Screens/Timeline/TimelineViewController.swift b/Tusker/Screens/Timeline/TimelineViewController.swift index 376fab48..1ab2f7fe 100644 --- a/Tusker/Screens/Timeline/TimelineViewController.swift +++ b/Tusker/Screens/Timeline/TimelineViewController.swift @@ -186,37 +186,39 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro func stateRestorationActivity() -> NSUserActivity? { let visible = collectionView.indexPathsForVisibleItems.sorted() let snapshot = dataSource.snapshot() + let visibleRect = CGRect(origin: collectionView.contentOffset, size: collectionView.bounds.size) + let midPoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY) guard let currentAccountID = mastodonController.accountInfo?.id, !visible.isEmpty, let statusesSection = snapshot.sectionIdentifiers.firstIndex(of: .statuses), - let firstVisible = visible.first(where: { $0.section == statusesSection }), - let lastVisible = visible.last(where: { $0.section == statusesSection }) else { + let rawCenterVisible = collectionView.indexPathForItem(at: midPoint), + let centerVisible = visible.first(where: { $0.section == statusesSection && $0 >= rawCenterVisible }) else { return nil } let allItems = snapshot.itemIdentifiers(inSection: .statuses) - let startIndex = max(0, firstVisible.row - 20) - let endIndex = min(allItems.count - 1, lastVisible.row + 20) + let startIndex = max(0, centerVisible.row - 20) + let endIndex = min(allItems.count - 1, centerVisible.row + 20) - let firstVisibleItem: Item + let centerVisibleItem: Item var items = allItems[startIndex...endIndex] if let gapIndex = items.firstIndex(of: .gap) { // if the gap is above the top visible item, we take everything below the gap // otherwise, we take everything above the gap - if gapIndex <= firstVisible.row { + if gapIndex <= centerVisible.row { items = allItems[(gapIndex + 1)...endIndex] - if gapIndex == firstVisible.row { - firstVisibleItem = allItems.first! + if gapIndex == centerVisible.row { + centerVisibleItem = allItems.first! } else { - assert(items.indices.contains(firstVisible.row)) - firstVisibleItem = allItems[firstVisible.row] + assert(items.indices.contains(centerVisible.row)) + centerVisibleItem = allItems[centerVisible.row] } } else { items = allItems[startIndex..