Skip to content

Commit

Permalink
Merge pull request #45 from daangn/feature/ben/MBP-6915-add-update-st…
Browse files Browse the repository at this point in the history
…rategy-option

MBP-6915 Adapter apply 인터페이스 개선
  • Loading branch information
OhKanghoon authored Sep 26, 2024
2 parents 0e80b84 + 453a131 commit 7b2c060
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 7 deletions.
40 changes: 33 additions & 7 deletions Sources/KarrotListKit/Adapter/CollectionViewAdapter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ final public class CollectionViewAdapter: NSObject {
private var isUpdating = false
private var queuedUpdate: (
list: List,
animatingDifferences: Bool,
updateStrategy: CollectionViewAdapterUpdateStrategy,
completion: (() -> Void)?
)?

Expand Down Expand Up @@ -96,19 +96,19 @@ final public class CollectionViewAdapter: NSObject {
///
/// - Parameters:
/// - list: The list that reflects the new state of the data in the collection view.
/// - animatingDifferences: If true, the framework animates the updates to the collection view. If false, the framework doesn’t animate the updates to the collection view.
/// - updateStrategy: The approaches for updating the content of a `UICollectionView`.
/// - completion: A closure to execute when the updates are complete. This closure has no return value and takes no parameters. The framework calls this closure from the main queue.
public func apply(
_ list: List,
animatingDifferences: Bool = true,
updateStrategy: CollectionViewAdapterUpdateStrategy = .animatedBatchUpdates,
completion: (() -> Void)? = nil
) {
guard let collectionView else {
return
}

guard isUpdating == false else {
queuedUpdate = (list, animatingDifferences, completion)
queuedUpdate = (list, updateStrategy, completion)
return
}

Expand All @@ -126,7 +126,7 @@ final public class CollectionViewAdapter: NSObject {
isUpdating = false
apply(
nextUpdate.list,
animatingDifferences: nextUpdate.animatingDifferences,
updateStrategy: nextUpdate.updateStrategy,
completion: nextUpdate.completion
)
} else {
Expand All @@ -144,23 +144,49 @@ final public class CollectionViewAdapter: NSObject {
return
}

if animatingDifferences {
switch updateStrategy {
case .animatedBatchUpdates:
performDifferentialUpdates(
old: self.list, new: list, completion: { flag in
overridedCompletion(flag)
}
)
} else {
case .nonanimatedBatchUpdates:
UIView.performWithoutAnimation {
performDifferentialUpdates(
old: self.list, new: list, completion: { flag in
overridedCompletion(flag)
}
)
}
case .reloadData:
self.list = list
collectionView.reloadData()
collectionView.layoutIfNeeded()
overridedCompletion(true)
}
}

/// Updates the UI to reflect the state of the data in the list, optionally animating the UI changes and executing a completion handler.
///
/// - Parameters:
/// - list: The list that reflects the new state of the data in the collection view.
/// - animatingDifferences: If true, the framework animates the updates to the collection view. If false, the framework doesn’t animate the updates to the collection view.
/// - completion: A closure to execute when the updates are complete. This closure has no return value and takes no parameters. The framework calls this closure from the main queue.
@_disfavoredOverload
@available(*, deprecated, renamed: "apply(_:updateStrategy:completion:)", message: "")
public func apply(
_ list: List,
animatingDifferences: Bool = true,
completion: (() -> Void)? = nil
) {
apply(
list,
updateStrategy: animatingDifferences ? .animatedBatchUpdates : .nonanimatedBatchUpdates,
completion: completion
)
}

/// Representation of the current state of the data in the collection view.
public func snapshot() -> List? {
list
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Copyright (c) 2024 Danggeun Market Inc.
//

import Foundation

/// The approaches for updating the content of a `UICollectionView`.
public enum CollectionViewAdapterUpdateStrategy {

/// Performs animated batch updates by calling `performBatchUpdates(…)` with the new content.
case animatedBatchUpdates

/// Performs non-animated batch updates by wrapping a call to `performBatchUpdates(…)` with the
/// new content within a `UIView.performWithoutAnimation(…)` closure.
///
/// More performant than `reloadData`, as it does not recreate and reconfigure all visible
/// cells.
case nonanimatedBatchUpdates

/// Performs non-animated updates by calling `reloadData()`, which recreates and reconfigures
/// all visible cells.
///
/// UIKit engineers have suggested that we should never need to call `reloadData` on updates,
/// and instead just use batch updates for all content updates.
case reloadData
}

0 comments on commit 7b2c060

Please sign in to comment.