Fix scroll position maintenance

This commit is contained in:
Justin Mazzocchi 2020-10-30 17:53:57 -07:00
parent 79b1c531f0
commit 7840a35e29
No known key found for this signature in database
GPG Key ID: E223E6937AAFB01C
5 changed files with 31 additions and 8 deletions

View File

@ -10,6 +10,8 @@ public enum CollectionItem: Hashable {
}
public extension CollectionItem {
typealias Id = String
struct StatusConfiguration: Hashable {
public let showContentToggled: Bool
public let showAttachmentsToggled: Bool
@ -32,6 +34,19 @@ public extension CollectionItem {
self.hasReplyFollowing = hasReplyFollowing
}
}
var itemId: Id? {
switch self {
case let .status(status, _):
return status.id
case .loadMore:
return nil
case let .account(account):
return account.id
case let .notification(notification, _):
return notification.id
}
}
}
public extension CollectionItem.StatusConfiguration {

View File

@ -42,3 +42,11 @@ final class TableViewDataSource: UITableViewDiffableDataSource<Int, CollectionIt
}
}
}
extension TableViewDataSource {
func indexPath(itemId: CollectionItem.Id) -> IndexPath? {
guard let item = snapshot().itemIdentifiers.first(where: { $0.itemId == itemId }) else { return nil }
return indexPath(for: item)
}
}

View File

@ -260,8 +260,8 @@ private extension TableViewController {
var offsetFromNavigationBar: CGFloat?
if
let item = update.maintainScrollPosition,
let indexPath = dataSource.indexPath(for: item),
let itemId = update.maintainScrollPositionItemId,
let indexPath = dataSource.indexPath(itemId: itemId),
let navigationBar = navigationController?.navigationBar {
let navigationBarMaxY = tableView.convert(navigationBar.bounds, from: navigationBar).maxY
offsetFromNavigationBar = tableView.rectForRow(at: indexPath).origin.y - navigationBarMaxY
@ -271,8 +271,8 @@ private extension TableViewController {
guard let self = self else { return }
if
let item = update.maintainScrollPosition,
let indexPath = self.dataSource.indexPath(for: item) {
let itemId = update.maintainScrollPositionItemId,
let indexPath = self.dataSource.indexPath(itemId: itemId) {
if self.viewModel.shouldAdjustContentInset {
self.tableView.contentInset.bottom = max(
0,

View File

@ -16,7 +16,7 @@ final public class CollectionItemsViewModel: ObservableObject {
private let eventsSubject = PassthroughSubject<CollectionItemEvent, Never>()
private let loadingSubject = PassthroughSubject<Bool, Never>()
private let expandAllSubject: CurrentValueSubject<ExpandAllState, Never>
private var maintainScrollPosition: CollectionItem?
private var maintainScrollPositionItemId: CollectionItem.Id?
private var topVisibleIndexPath = IndexPath(item: 0, section: 0)
private let lastReadId = CurrentValueSubject<String?, Never>(nil)
private var lastSelectedLoadMore: LoadMore?
@ -57,7 +57,7 @@ extension CollectionItemsViewModel: CollectionViewModel {
public var updates: AnyPublisher<CollectionUpdate, Never> {
items.map { [weak self] in
CollectionUpdate(items: $0,
maintainScrollPosition: self?.maintainScrollPosition)
maintainScrollPositionItemId: self?.maintainScrollPositionItemId)
}
.eraseToAnyPublisher()
}
@ -267,7 +267,7 @@ private extension CollectionItemsViewModel {
}
func process(items: [[CollectionItem]]) {
maintainScrollPosition = itemForScrollPositionMaintenance(newItems: items)
maintainScrollPositionItemId = itemForScrollPositionMaintenance(newItems: items)?.itemId
self.items.send(items)
let itemsSet = Set(items.reduce([], +))

View File

@ -2,5 +2,5 @@
public struct CollectionUpdate: Hashable {
public let items: [[CollectionItem]]
public let maintainScrollPosition: CollectionItem?
public let maintainScrollPositionItemId: String?
}