Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove nested calls to performBatchUpdates when updating header/footer #10

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 34 additions & 6 deletions Sources/ComposedUI/CollectionView/CollectionCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -567,9 +567,7 @@ extension CollectionCoordinator: SectionProviderMappingDelegate {
let elementsProvider = self.elementsProvider(for: sectionIndex)
let section = self.mapper.provider.sections[sectionIndex]

// Without performing these changes inside a batch updates the header
// may briefly be hidden, causing a "flash" to occur.
collectionView.performBatchUpdates {
func reloadHeader() {
let context = UICollectionViewFlowLayoutInvalidationContext()
context.invalidateSupplementaryElements(ofKind: UICollectionView.elementKindSectionHeader, at: [IndexPath(item: 0, section: sectionIndex)])
invalidateLayout(with: context)
Expand All @@ -582,6 +580,22 @@ extension CollectionCoordinator: SectionProviderMappingDelegate {
header.configure(headerView, sectionIndex, section)
}
}

// The header reload should always be inside a `performBatchUpdates` to prevent a "flash"
// from occurring when refreshing, but if the update is inside a nested
// `performBatchUpdates` it can cause some of the indexes to be incorrect. This could be a
// bug within the caller, but I think it's more likely that calling `performBatchUpdates`
// can trigger a layout update, but being mid-update means the indexes are not yet all in
// sync with what the collection view knows.
if isPerformingUpdates {
reloadHeader()
} else {
isPerformingUpdates = true
collectionView.performBatchUpdates {
reloadHeader()
isPerformingUpdates = false
}
}
}

public func mappingDidInvalidateFooter(at sectionIndex: Int) {
Expand All @@ -593,9 +607,7 @@ extension CollectionCoordinator: SectionProviderMappingDelegate {

debugLog("Section \(sectionIndex) invalidated footer")

// Without performing these changes inside a batch updates the footer
// may briefly be hidden, causing a "flash" to occur.
collectionView.performBatchUpdates {
func reloadFooter() {
let context = UICollectionViewFlowLayoutInvalidationContext()
context.invalidateSupplementaryElements(ofKind: UICollectionView.elementKindSectionFooter, at: [IndexPath(item: 0, section: sectionIndex)])
invalidateLayout(with: context)
Expand All @@ -611,6 +623,22 @@ extension CollectionCoordinator: SectionProviderMappingDelegate {
footer.configure(footerView, sectionIndex, section)
}
}

// The footer reload should always be inside a `performBatchUpdates` to prevent a "flash"
// from occurring when refreshing, but if the update is inside a nested
// `performBatchUpdates` it can cause some of the indexes to be incorrect. This could be a
// bug within the caller, but I think it's more likely that calling `performBatchUpdates`
// can trigger a layout update, but being mid-update means the indexes are not yet all in
// sync with what the collection view knows.
if isPerformingUpdates {
reloadFooter()
} else {
isPerformingUpdates = true
collectionView.performBatchUpdates {
reloadFooter()
isPerformingUpdates = false
}
}
}
}

Expand Down