From 37dd500e5dcd9486503f2caed5a4b377be37d929 Mon Sep 17 00:00:00 2001 From: Kyle Van Essen Date: Mon, 12 Sep 2022 15:34:05 -0700 Subject: [PATCH 1/2] Revert "Merge pull request #411 from kyleve/kve/fix-insert-animations-for-single-row-sections" This reverts commit 18550a56f7f75d6ec335ba4870da08b9c55ea88e, reversing changes made to 2ae3d859bb55e9422811a5f9b632f65c36a059b8. --- CHANGELOG.md | 2 + ...tionViewDictionaryDemoViewController.swift | 16 +- .../Sources/Layout/CollectionViewLayout.swift | 139 ++---------------- 3 files changed, 20 insertions(+), 137 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc36a1886..086c16dcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ ### Removed +- **Revert from 7.0.0**: _"When a section is inserted or removed, and that section has only one item, and no header or footer, the insertion or removal animation for the section's singular item will be used instead."_ This was causing crashes in `initialLayoutAttributesForAppearingItem` and `finalLayoutAttributesForDisappearingItem` due to index path mismatches. + ### Changed ### Misc diff --git a/Demo/Sources/Demos/Demo Screens/CollectionViewDictionaryDemoViewController.swift b/Demo/Sources/Demos/Demo Screens/CollectionViewDictionaryDemoViewController.swift index b711212c3..872a536a9 100644 --- a/Demo/Sources/Demos/Demo Screens/CollectionViewDictionaryDemoViewController.swift +++ b/Demo/Sources/Demos/Demo Screens/CollectionViewDictionaryDemoViewController.swift @@ -135,8 +135,7 @@ final public class CollectionViewDictionaryDemoViewController : UIViewController content += Section("empty") { section in section += WordRow( title: "No Results For '\(state.value.filter)'", - detail: "Please enter a different search.", - animations: .scaleUp + detail: "Please enter a different search." ) } } @@ -203,11 +202,10 @@ fileprivate struct SectionHeader : BlueprintHeaderFooterContent, Equatable } -fileprivate struct WordRow : BlueprintItemContent +fileprivate struct WordRow : BlueprintItemContent, Equatable { var title : String var detail : String - var animations : ItemInsertAndRemoveAnimations? // MARK: BlueprintItemElement @@ -234,16 +232,6 @@ fileprivate struct WordRow : BlueprintItemContent var identifierValue: String { self.title } - - func isEquivalent(to other: WordRow) -> Bool { - title == other.title && detail == other.detail - } - - var defaultItemProperties: DefaultProperties { - .defaults { - $0.insertAndRemoveAnimations = animations - } - } } diff --git a/ListableUI/Sources/Layout/CollectionViewLayout.swift b/ListableUI/Sources/Layout/CollectionViewLayout.swift index f11ae57cb..6932a5a04 100644 --- a/ListableUI/Sources/Layout/CollectionViewLayout.swift +++ b/ListableUI/Sources/Layout/CollectionViewLayout.swift @@ -80,7 +80,7 @@ final class CollectionViewLayout : UICollectionViewLayout self.previousLayout = self.layout - self.changesDuringCurrentUpdate = UpdateItems() + self.changesDuringCurrentUpdate = UpdateItems(with: []) self.viewProperties = CollectionViewLayoutProperties() @@ -388,7 +388,7 @@ final class CollectionViewLayout : UICollectionViewLayout { super.prepare() - self.changesDuringCurrentUpdate = UpdateItems() + self.changesDuringCurrentUpdate = UpdateItems(with: []) let size = self.collectionView?.bounds.size ?? .zero @@ -421,11 +421,7 @@ final class CollectionViewLayout : UICollectionViewLayout { super.prepare(forCollectionViewUpdates: updateItems) - self.changesDuringCurrentUpdate = UpdateItems( - with: updateItems, - oldContent: self.previousLayout.content, - newContent: self.layout.content - ) + self.changesDuringCurrentUpdate = UpdateItems(with: updateItems) } // @@ -436,7 +432,7 @@ final class CollectionViewLayout : UICollectionViewLayout { super.finalizeCollectionViewUpdates() - self.changesDuringCurrentUpdate = UpdateItems() + self.changesDuringCurrentUpdate = UpdateItems(with: []) } // @@ -542,23 +538,9 @@ final class CollectionViewLayout : UICollectionViewLayout override func initialLayoutAttributesForAppearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? { - let changes = self.changesDuringCurrentUpdate - - let wasInserted = changes.insertedItems.contains(.init(newIndexPath: itemIndexPath)) - - // If we are the only item in a newly inserted section, and that section has - // no header or footer, we can effectively treat the insertion as a row insertion, - // and use the item's row insertion animation. - - func wasInsertedInSingleItemSection() -> Bool { - guard let section = changes.insertedSection(at: itemIndexPath.section) else { - return false - } - - return section.isSingleItemSection - } + let wasInserted = self.changesDuringCurrentUpdate.insertedItems.contains(.init(newIndexPath: itemIndexPath)) - if wasInserted || wasInsertedInSingleItemSection() { + if wasInserted { let item = self.layout.content.item(at: itemIndexPath) let attributes = item.layoutAttributes(with: itemIndexPath) let animations = self.animations(for: item) @@ -569,7 +551,7 @@ final class CollectionViewLayout : UICollectionViewLayout return attributes } else { - let wasSectionInserted = changes.insertedSectionIndexes.contains(itemIndexPath.section) + let wasSectionInserted = self.changesDuringCurrentUpdate.insertedSections.contains(.init(newIndex: itemIndexPath.section)) let attributes = super.initialLayoutAttributesForAppearingItem(at: itemIndexPath) @@ -583,23 +565,9 @@ final class CollectionViewLayout : UICollectionViewLayout override func finalLayoutAttributesForDisappearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? { - let changes = self.changesDuringCurrentUpdate - - let wasItemDeleted = changes.deletedItems.contains(.init(oldIndexPath: itemIndexPath)) - - // If we are the only item in a deleted section, and that section has - // no header or footer, we can effectively treat the insertion as a row deletion, - // and use the item's row deletion animation. - - func wasDeletedFromSingleItemSection() -> Bool { - guard let section = changes.deletedSection(at: itemIndexPath.section) else { - return false - } - - return section.isSingleItemSection - } - - if wasItemDeleted || wasDeletedFromSingleItemSection() { + let wasItemDeleted = self.changesDuringCurrentUpdate.deletedItems.contains(.init(oldIndexPath: itemIndexPath)) + + if wasItemDeleted { let item = self.previousLayout.content.item(at: itemIndexPath) let attributes = item.layoutAttributes(with: itemIndexPath) let animations = self.animations(for: item) @@ -610,7 +578,7 @@ final class CollectionViewLayout : UICollectionViewLayout return attributes } else { - let wasSectionDeleted = changes.deletedSectionIndexes.contains(itemIndexPath.section) + let wasSectionDeleted = self.changesDuringCurrentUpdate.deletedSections.contains(.init(oldIndex: itemIndexPath.section)) let attributes = super.finalLayoutAttributesForDisappearingItem(at: itemIndexPath) @@ -624,7 +592,7 @@ final class CollectionViewLayout : UICollectionViewLayout override func initialLayoutAttributesForAppearingSupplementaryElement(ofKind elementKind: String, at elementIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? { - let wasInserted = self.changesDuringCurrentUpdate.insertedSectionIndexes.contains(elementIndexPath.section) + let wasInserted = self.changesDuringCurrentUpdate.insertedSections.contains(.init(newIndex: elementIndexPath.section)) let attributes = super.initialLayoutAttributesForAppearingSupplementaryElement(ofKind: elementKind, at: elementIndexPath) if wasInserted == false { @@ -636,7 +604,7 @@ final class CollectionViewLayout : UICollectionViewLayout override func finalLayoutAttributesForDisappearingSupplementaryElement(ofKind elementKind: String, at elementIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? { - let wasDeleted = self.changesDuringCurrentUpdate.deletedSectionIndexes.contains(elementIndexPath.section) + let wasDeleted = self.changesDuringCurrentUpdate.deletedSections.contains(.init(oldIndex: elementIndexPath.section)) let attributes = super.finalLayoutAttributesForDisappearingSupplementaryElement(ofKind: elementKind, at: elementIndexPath) if wasDeleted == false { @@ -740,30 +708,15 @@ public protocol CollectionViewLayoutDelegate : AnyObject fileprivate struct UpdateItems : Equatable { let insertedSections : Set - let insertedSectionIndexes : Set - let deletedSections : Set - let deletedSectionIndexes : Set let insertedItems : Set let deletedItems : Set - - init() { - self.insertedSections = [] - self.insertedSectionIndexes = [] - self.deletedSections = [] - self.deletedSectionIndexes = [] - self.insertedItems = [] - self.deletedItems = [] - } - init(with updateItems : [UICollectionViewUpdateItem], oldContent : ListLayoutContent, newContent: ListLayoutContent) + init(with updateItems : [UICollectionViewUpdateItem]) { var insertedSections = Set() - var insertedSectionIndexes = Set() - var deletedSections = Set() - var deletedSectionIndexes = Set() var insertedItems = Set() var deletedItems = Set() @@ -774,18 +727,7 @@ fileprivate struct UpdateItems : Equatable let indexPath = item.indexPathAfterUpdate! if indexPath.item == NSNotFound { - insertedSectionIndexes.insert(indexPath.section) - - let section = newContent.sections[indexPath.section] - - insertedSections.insert( - .init( - newIndex: indexPath.section, - itemCount: section.items.count, - hasHeader: section.header.isPopulated, - hasFooter: section.footer.isPopulated - ) - ) + insertedSections.insert(.init(newIndex: indexPath.section)) } else { insertedItems.insert(.init(newIndexPath: indexPath)) } @@ -794,19 +736,7 @@ fileprivate struct UpdateItems : Equatable let indexPath = item.indexPathBeforeUpdate! if indexPath.item == NSNotFound { - deletedSectionIndexes.insert(indexPath.section) - - let section = oldContent.sections[indexPath.section] - - deletedSections.insert( - .init( - oldIndex: indexPath.section, - itemCount: section.items.count, - hasHeader: section.header.isPopulated, - hasFooter: section.footer.isPopulated - ) - ) - + deletedSections.insert(.init(oldIndex: indexPath.section)) } else { deletedItems.insert(.init(oldIndexPath: indexPath)) } @@ -820,57 +750,20 @@ fileprivate struct UpdateItems : Equatable } self.insertedSections = insertedSections - self.insertedSectionIndexes = insertedSectionIndexes - self.deletedSections = deletedSections - self.deletedSectionIndexes = deletedSectionIndexes self.insertedItems = insertedItems self.deletedItems = deletedItems } - - func insertedSection(at index : Int) -> InsertSection? { - guard insertedSectionIndexes.contains(index) else { return nil } - - return insertedSections.first { - $0.newIndex == index - } - } - - func deletedSection(at index : Int) -> DeleteSection? { - guard deletedSectionIndexes.contains(index) else { return nil } - - return deletedSections.first { - $0.oldIndex == index - } - } struct InsertSection : Hashable { var newIndex : Int - - var itemCount : Int - - var hasHeader : Bool - var hasFooter : Bool - - var isSingleItemSection : Bool { - itemCount == 1 && hasHeader == false && hasFooter == false - } } struct DeleteSection : Hashable { var oldIndex : Int - - var itemCount : Int - - var hasHeader : Bool - var hasFooter : Bool - - var isSingleItemSection : Bool { - itemCount == 1 && hasHeader == false && hasFooter == false - } } struct InsertItem : Hashable From 25ffa0be9235f9c5dc66d1feeaf5f83faefb2631 Mon Sep 17 00:00:00 2001 From: Kyle Van Essen Date: Mon, 12 Sep 2022 15:34:55 -0700 Subject: [PATCH 2/2] Update version to 7.1.2 --- CHANGELOG.md | 11 ++++++++--- Podfile.lock | 12 ++++++------ version.rb | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 086c16dcd..9ab1e23a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,14 +6,18 @@ ### Removed -- **Revert from 7.0.0**: _"When a section is inserted or removed, and that section has only one item, and no header or footer, the insertion or removal animation for the section's singular item will be used instead."_ This was causing crashes in `initialLayoutAttributesForAppearingItem` and `finalLayoutAttributesForDisappearingItem` due to index path mismatches. - ### Changed ### Misc # Past Releases +# [7.1.2] - 2022-09-12 + +### Removed + +- **Revert from 7.0.0**: _"When a section is inserted or removed, and that section has only one item, and no header or footer, the insertion or removal animation for the section's singular item will be used instead."_ This was causing crashes in `initialLayoutAttributesForAppearingItem` and `finalLayoutAttributesForDisappearingItem` due to index path mismatches. + # [7.1.1] - 2022-09-06 ### Fixed @@ -774,7 +778,8 @@ listActions.scrolling.scrollToSection( Earlier releases were ad-hoc and not tracked. To see all changes, please reference [closed PRs on Github](https://github.com/kyleve/Listable/pulls?q=is%3Apr+is%3Aclosed). -[Main]: https://github.com/kyleve/Listable/compare/7.1.1...HEAD +[Main]: https://github.com/kyleve/Listable/compare/7.1.2...HEAD +[7.1.2]: https://github.com/kyleve/Listable/compare/7.1.1...7.1.2 [7.1.1]: https://github.com/kyleve/Listable/compare/7.1.0...7.1.1 [7.1.0]: https://github.com/kyleve/Listable/compare/7.0.0...7.1.0 [7.0.0]: https://github.com/kyleve/Listable/compare/6.0.0...7.0.0 diff --git a/Podfile.lock b/Podfile.lock index 7832b60e2..9649bfea9 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -2,16 +2,16 @@ PODS: - BlueprintUI (0.45.0) - BlueprintUICommonControls (0.45.0): - BlueprintUI (= 0.45.0) - - BlueprintUILists (7.1.1): + - BlueprintUILists (7.1.2): - BlueprintUI - ListableUI - - BlueprintUILists/Tests (7.1.1): + - BlueprintUILists/Tests (7.1.2): - BlueprintUI - BlueprintUICommonControls - ListableUI - EnglishDictionary (1.0.0.LOCAL) - - ListableUI (7.1.1) - - ListableUI/Tests (7.1.1): + - ListableUI (7.1.2) + - ListableUI/Tests (7.1.2): - EnglishDictionary - Snapshot - Snapshot (1.0.0.LOCAL) @@ -46,9 +46,9 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: BlueprintUI: 93a2cb4c435df2eee064634cd6cfc25d135fa094 BlueprintUICommonControls: ec80ccd2ea2d8b7f4e554c6c0a7ab68812da9010 - BlueprintUILists: ca80569eca5e27d56d8389c84d53cbd039226084 + BlueprintUILists: f5355635e05df3c888aa5e3e752fed244c35f303 EnglishDictionary: f03968b9382ddc5c8dd63535efbf783c6cd45f1c - ListableUI: a5a94bfe7135971cb31ce779032071c30965ea9a + ListableUI: fd902039ed26ffbae01d6ca27a17c9d9a99e8197 Snapshot: cda3414db426919d09f775434b36289c8e864183 PODFILE CHECKSUM: 505f47e09640e9b7eadef9a138cfeed056359f76 diff --git a/version.rb b/version.rb index 6a19e6abe..23b15aa2f 100644 --- a/version.rb +++ b/version.rb @@ -1,3 +1,3 @@ # frozen_string_literal: true -LISTABLE_VERSION ||= '7.1.1' +LISTABLE_VERSION ||= '7.1.2'