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 { public extension CollectionItem {
typealias Id = String
struct StatusConfiguration: Hashable { struct StatusConfiguration: Hashable {
public let showContentToggled: Bool public let showContentToggled: Bool
public let showAttachmentsToggled: Bool public let showAttachmentsToggled: Bool
@ -32,6 +34,19 @@ public extension CollectionItem {
self.hasReplyFollowing = hasReplyFollowing 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 { 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? var offsetFromNavigationBar: CGFloat?
if if
let item = update.maintainScrollPosition, let itemId = update.maintainScrollPositionItemId,
let indexPath = dataSource.indexPath(for: item), let indexPath = dataSource.indexPath(itemId: itemId),
let navigationBar = navigationController?.navigationBar { let navigationBar = navigationController?.navigationBar {
let navigationBarMaxY = tableView.convert(navigationBar.bounds, from: navigationBar).maxY let navigationBarMaxY = tableView.convert(navigationBar.bounds, from: navigationBar).maxY
offsetFromNavigationBar = tableView.rectForRow(at: indexPath).origin.y - navigationBarMaxY offsetFromNavigationBar = tableView.rectForRow(at: indexPath).origin.y - navigationBarMaxY
@ -271,8 +271,8 @@ private extension TableViewController {
guard let self = self else { return } guard let self = self else { return }
if if
let item = update.maintainScrollPosition, let itemId = update.maintainScrollPositionItemId,
let indexPath = self.dataSource.indexPath(for: item) { let indexPath = self.dataSource.indexPath(itemId: itemId) {
if self.viewModel.shouldAdjustContentInset { if self.viewModel.shouldAdjustContentInset {
self.tableView.contentInset.bottom = max( self.tableView.contentInset.bottom = max(
0, 0,

View file

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

View file

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