From cba963a81eb84f0c70c8978f147267a181a0c450 Mon Sep 17 00:00:00 2001 From: CMK Date: Mon, 11 Oct 2021 14:11:10 +0800 Subject: [PATCH] chore: update snapshot update logic for iOS 15 new default behavior --- Mastodon.xcodeproj/project.pbxproj | 8 ++++ .../UICollectionViewDiffableDataSource.swift | 40 +++++++++++++++++++ .../UITableViewDiffableDataSource.swift | 40 +++++++++++++++++++ .../HashtagTimelineViewModel+Diffable.swift | 2 +- .../HomeTimelineViewModel+Diffable.swift | 2 +- .../PublicTimelineViewModel.swift | 2 +- .../Thread/ThreadViewModel+Diffable.swift | 2 +- 7 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 Mastodon/Extension/UICollectionViewDiffableDataSource.swift create mode 100644 Mastodon/Extension/UITableViewDiffableDataSource.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 009fbb44..7d72f039 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -361,6 +361,8 @@ DB73BF43271192BB00781945 /* InstanceService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB73BF42271192BB00781945 /* InstanceService.swift */; }; DB73BF45271195AC00781945 /* APIService+CoreData+Instance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB73BF44271195AC00781945 /* APIService+CoreData+Instance.swift */; }; DB73BF47271199CA00781945 /* Instance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB73BF46271199CA00781945 /* Instance.swift */; }; + DB73BF4927140BA300781945 /* UICollectionViewDiffableDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB73BF4827140BA300781945 /* UICollectionViewDiffableDataSource.swift */; }; + DB73BF4B27140C0800781945 /* UITableViewDiffableDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB73BF4A27140C0800781945 /* UITableViewDiffableDataSource.swift */; }; DB75BF1E263C1C1B00EDBF1F /* CustomScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB75BF1D263C1C1B00EDBF1F /* CustomScheduler.swift */; }; DB789A0B25F9F2950071ACA0 /* ComposeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB789A0A25F9F2950071ACA0 /* ComposeViewController.swift */; }; DB789A1225F9F2CC0071ACA0 /* ComposeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB789A1125F9F2CC0071ACA0 /* ComposeViewModel.swift */; }; @@ -1153,6 +1155,8 @@ DB73BF42271192BB00781945 /* InstanceService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceService.swift; sourceTree = ""; }; DB73BF44271195AC00781945 /* APIService+CoreData+Instance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+CoreData+Instance.swift"; sourceTree = ""; }; DB73BF46271199CA00781945 /* Instance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Instance.swift; sourceTree = ""; }; + DB73BF4827140BA300781945 /* UICollectionViewDiffableDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UICollectionViewDiffableDataSource.swift; sourceTree = ""; }; + DB73BF4A27140C0800781945 /* UITableViewDiffableDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITableViewDiffableDataSource.swift; sourceTree = ""; }; DB75BF1D263C1C1B00EDBF1F /* CustomScheduler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomScheduler.swift; sourceTree = ""; }; DB789A0A25F9F2950071ACA0 /* ComposeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewController.swift; sourceTree = ""; }; DB789A1125F9F2CC0071ACA0 /* ComposeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewModel.swift; sourceTree = ""; }; @@ -2748,6 +2752,8 @@ DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */, DBCC3B2F261440A50045B23D /* UITabBarController.swift */, DBCC3B35261440BA0045B23D /* UINavigationController.swift */, + DB73BF4827140BA300781945 /* UICollectionViewDiffableDataSource.swift */, + DB73BF4A27140C0800781945 /* UITableViewDiffableDataSource.swift */, ); path = Extension; sourceTree = ""; @@ -4014,6 +4020,7 @@ DB59F11825EFA35B001F1DAB /* StripProgressView.swift in Sources */, DB59F10425EF5EBC001F1DAB /* TableViewCellHeightCacheableContainer.swift in Sources */, DBF9814C265E339500E4BA07 /* ProfileFieldAddEntryCollectionViewCell.swift in Sources */, + DB73BF4927140BA300781945 /* UICollectionViewDiffableDataSource.swift in Sources */, DBA5E7AB263BD3F5004598BB /* TimelineTableViewCellContextMenuConfiguration.swift in Sources */, DB73B490261F030A002E9E9F /* SafariActivity.swift in Sources */, DB6D1B44263691CF00ACB481 /* Mastodon+API+Subscriptions+Policy.swift in Sources */, @@ -4110,6 +4117,7 @@ DB1E346825F518E20079D7DF /* CategoryPickerSection.swift in Sources */, 2D61254D262547C200299647 /* APIService+Notification.swift in Sources */, DB040ED126538E3D00BEE9D8 /* Trie.swift in Sources */, + DB73BF4B27140C0800781945 /* UITableViewDiffableDataSource.swift in Sources */, DBB525642612C988002F1F29 /* MeProfileViewModel.swift in Sources */, 5BB04FE9262EFC300043BFF6 /* ReportedStatusTableviewCell.swift in Sources */, DBAE3F822615DDA3004B8251 /* ProfileViewController+UserProvider.swift in Sources */, diff --git a/Mastodon/Extension/UICollectionViewDiffableDataSource.swift b/Mastodon/Extension/UICollectionViewDiffableDataSource.swift new file mode 100644 index 00000000..07d2fbd1 --- /dev/null +++ b/Mastodon/Extension/UICollectionViewDiffableDataSource.swift @@ -0,0 +1,40 @@ +// +// UICollectionViewDiffableDataSource.swift +// Mastodon +// +// Created by Cirno MainasuK on 2021-10-11. +// + +import UIKit + +// ref: https://www.jessesquires.com/blog/2021/07/08/diffable-data-source-behavior-changes-and-reconfiguring-cells-in-ios-15/ +extension UICollectionViewDiffableDataSource { + func reloadData( + snapshot: NSDiffableDataSourceSnapshot, + completion: (() -> Void)? = nil + ) { + if #available(iOS 15.0, *) { + self.applySnapshotUsingReloadData(snapshot, completion: completion) + } else { + self.apply(snapshot, animatingDifferences: false, completion: completion) + } + } + + func applySnapshot( + _ snapshot: NSDiffableDataSourceSnapshot, + animated: Bool, + completion: (() -> Void)? = nil) { + + if #available(iOS 15.0, *) { + self.apply(snapshot, animatingDifferences: animated, completion: completion) + } else { + if animated { + self.apply(snapshot, animatingDifferences: true, completion: completion) + } else { + UIView.performWithoutAnimation { + self.apply(snapshot, animatingDifferences: true, completion: completion) + } + } + } + } +} diff --git a/Mastodon/Extension/UITableViewDiffableDataSource.swift b/Mastodon/Extension/UITableViewDiffableDataSource.swift new file mode 100644 index 00000000..5006417a --- /dev/null +++ b/Mastodon/Extension/UITableViewDiffableDataSource.swift @@ -0,0 +1,40 @@ +// +// UITableViewDiffableDataSource.swift +// Mastodon +// +// Created by Cirno MainasuK on 2021-10-11. +// + +import UIKit + +// ref: https://www.jessesquires.com/blog/2021/07/08/diffable-data-source-behavior-changes-and-reconfiguring-cells-in-ios-15/ +extension UITableViewDiffableDataSource { + func reloadData( + snapshot: NSDiffableDataSourceSnapshot, + completion: (() -> Void)? = nil + ) { + if #available(iOS 15.0, *) { + self.applySnapshotUsingReloadData(snapshot, completion: completion) + } else { + self.apply(snapshot, animatingDifferences: false, completion: completion) + } + } + + func applySnapshot( + _ snapshot: NSDiffableDataSourceSnapshot, + animated: Bool, + completion: (() -> Void)? = nil) { + + if #available(iOS 15.0, *) { + self.apply(snapshot, animatingDifferences: animated, completion: completion) + } else { + if animated { + self.apply(snapshot, animatingDifferences: true, completion: completion) + } else { + UIView.performWithoutAnimation { + self.apply(snapshot, animatingDifferences: true, completion: completion) + } + } + } + } +} diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift index 23ed744f..a601eb92 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift @@ -89,7 +89,7 @@ extension HashtagTimelineViewModel { } DispatchQueue.main.async { - diffableDataSource.apply(newSnapshot, animatingDifferences: false) { + diffableDataSource.reloadData(snapshot: newSnapshot) { tableView.scrollToRow(at: difference.targetIndexPath, at: .top, animated: false) tableView.contentOffset.y = tableView.contentOffset.y - difference.offset self.isFetchingLatestTimeline.value = false diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift index 73d2c173..e87cab1c 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift @@ -119,7 +119,7 @@ extension HomeTimelineViewModel: NSFetchedResultsControllerDelegate { return } - diffableDataSource.apply(newSnapshot, animatingDifferences: false) { + diffableDataSource.reloadData(snapshot: newSnapshot) { tableView.scrollToRow(at: difference.targetIndexPath, at: .top, animated: false) tableView.contentOffset.y = tableView.contentOffset.y - difference.offset self.isFetchingLatestTimeline.value = false diff --git a/Mastodon/Scene/PublicTimeline/PublicTimelineViewModel.swift b/Mastodon/Scene/PublicTimeline/PublicTimelineViewModel.swift index c3b1a3d4..6d6ecbd3 100644 --- a/Mastodon/Scene/PublicTimeline/PublicTimelineViewModel.swift +++ b/Mastodon/Scene/PublicTimeline/PublicTimelineViewModel.swift @@ -102,7 +102,7 @@ class PublicTimelineViewModel: NSObject { return } - diffableDataSource.apply(snapshot, animatingDifferences: false) { + diffableDataSource.reloadData(snapshot: snapshot) { tableView.scrollToRow(at: difference.targetIndexPath, at: .top, animated: false) tableView.contentOffset.y = tableView.contentOffset.y - difference.offset self.isFetchingLatestTimeline.value = false diff --git a/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift b/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift index 5bbc383e..853bee9d 100644 --- a/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift +++ b/Mastodon/Scene/Thread/ThreadViewModel+Diffable.swift @@ -135,7 +135,7 @@ extension ThreadViewModel { // save height before cell reuse let oldRootCellHeight = oldRootCell?.frame.height - diffableDataSource.apply(newSnapshot, animatingDifferences: false) { + diffableDataSource.reloadData(snapshot: newSnapshot) { guard let _ = rootItem else { return }