Skip to content

Commit 9ddb267

Browse files
authored
Add Cell highlight animation customizable (#2)
1 parent 5563166 commit 9ddb267

File tree

2 files changed

+63
-15
lines changed

2 files changed

+63
-15
lines changed

Sources/DynamicList/DynamicListView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public final class DynamicListView<Section: Hashable, Data: Hashable>: UIView,
5151
withConfiguration contentConfiguration: @escaping @MainActor (
5252
VersatileCell, UICellConfigurationState
5353
) -> Configuration
54-
) -> some UICollectionViewCell {
54+
) -> VersatileCell {
5555

5656
let _reuseIdentifier = reuseIdentifier ?? "\(file):\(line):\(column)"
5757

@@ -83,7 +83,7 @@ public final class DynamicListView<Section: Hashable, Data: Hashable>: UIView,
8383
column: UInt = #column,
8484
reuseIdentifier: String? = nil,
8585
@ViewBuilder content: @escaping @MainActor (UICellConfigurationState) -> some View
86-
) -> UICollectionViewCell {
86+
) -> VersatileCell {
8787

8888
if #available(iOS 16, *) {
8989
return self.cell(

Sources/DynamicList/VersatileCell.swift

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,72 @@
11
import UIKit
22

3-
open class VersatileCell: UICollectionViewCell {
3+
public struct CellHighlightAnimationContext {
4+
public let cell: UICollectionViewCell
5+
}
6+
7+
public protocol CellHighlightAnimation {
8+
9+
@MainActor
10+
func onChange(isHighlighted: Bool, context: CellHighlightAnimationContext)
11+
}
12+
13+
public struct DisabledCellHighlightAnimation: CellHighlightAnimation {
14+
15+
public func onChange(isHighlighted: Bool, context: CellHighlightAnimationContext) {
16+
// no operation
17+
}
18+
}
419

5-
let animator = UIViewPropertyAnimator(duration: 0.4, dampingRatio: 1)
20+
public struct ShrinkCellHighlightAnimation: CellHighlightAnimation {
21+
22+
public func onChange(isHighlighted: Bool, context: CellHighlightAnimationContext) {
23+
24+
let animator = UIViewPropertyAnimator(duration: 0.4, dampingRatio: 1)
25+
26+
if isHighlighted {
27+
animator.addAnimations {
28+
context.cell.transform = .init(scaleX: 0.95, y: 0.95)
29+
}
30+
} else {
31+
animator.addAnimations {
32+
context.cell.transform = .identity
33+
}
34+
}
35+
animator.startAnimation()
36+
}
37+
}
38+
39+
extension CellHighlightAnimation {
40+
41+
public static func shrink(
42+
duration: TimeInterval = 0.4,
43+
dampingRatio: CGFloat = 1
44+
) -> Self where Self == ShrinkCellHighlightAnimation {
45+
ShrinkCellHighlightAnimation()
46+
}
47+
48+
}
49+
50+
extension CellHighlightAnimation where Self == DisabledCellHighlightAnimation {
51+
public static var disabled: Self {
52+
DisabledCellHighlightAnimation()
53+
}
54+
}
55+
56+
open class VersatileCell: UICollectionViewCell {
657

758
open override var isHighlighted: Bool {
859
didSet {
960
guard oldValue != isHighlighted else { return }
10-
11-
if isHighlighted {
12-
animator.addAnimations { [self] in
13-
transform = .init(scaleX: 0.95, y: 0.95)
14-
}
15-
} else {
16-
animator.addAnimations { [self] in
17-
transform = .identity
18-
}
19-
}
20-
animator.startAnimation()
61+
_highlightAnimation.onChange(isHighlighted: isHighlighted, context: .init(cell: self))
2162
}
2263
}
2364

2465
public var _updateConfigurationHandler:
2566
@MainActor (_ cell: VersatileCell, _ state: UICellConfigurationState) -> Void = { _, _ in }
2667

68+
private var _highlightAnimation: any CellHighlightAnimation = .disabled
69+
2770
public override init(
2871
frame: CGRect
2972
) {
@@ -92,4 +135,9 @@ open class VersatileCell: UICollectionViewCell {
92135
}
93136
}
94137

138+
public func highlightAnimation(_ animation: any CellHighlightAnimation) -> Self {
139+
self._highlightAnimation = animation
140+
return self
141+
}
142+
95143
}

0 commit comments

Comments
 (0)