@@ -15,10 +15,6 @@ import RxCocoa
15
15
#endif
16
16
import Differentiator
17
17
18
- /*
19
- This is commented becuse collection view has bugs when doing animated updates.
20
- Take a look at randomized sections.
21
- */
22
18
open class RxCollectionViewSectionedAnimatedDataSource < S: AnimatableSectionModelType >
23
19
: CollectionViewSectionedDataSource < S >
24
20
, RxCollectionViewDataSourceType {
@@ -47,69 +43,12 @@ open class RxCollectionViewSectionedAnimatedDataSource<S: AnimatableSectionModel
47
43
moveItem: moveItem,
48
44
canMoveItemAtIndexPath: canMoveItemAtIndexPath
49
45
)
50
-
51
- self . partialUpdateEvent
52
- // so in case it does produce a crash, it will be after the data has changed
53
- . observeOn ( MainScheduler . asyncInstance)
54
- // Collection view has issues digesting fast updates, this should
55
- // help to alleviate the issues with them.
56
- . throttle ( 0.5 , scheduler: MainScheduler . instance)
57
- . subscribe ( onNext: { [ weak self] event in
58
- self ? . collectionView ( event. 0 , throttledObservedEvent: event. 1 )
59
- } )
60
- . disposed ( by: disposeBag)
61
46
}
62
-
63
- // For some inexplicable reason, when doing animated updates first time
64
- // it crashes. Still need to figure out that one.
47
+
48
+ // there is no longer limitation to load initial sections with reloadData
49
+ // but it is kept as a feature everyone got used to
65
50
var dataSet = false
66
51
67
- private let disposeBag = DisposeBag ( )
68
-
69
- // This subject and throttle are here
70
- // because collection view has problems processing animated updates fast.
71
- // This should somewhat help to alleviate the problem.
72
- private let partialUpdateEvent = PublishSubject < ( UICollectionView , Event < Element > ) > ( )
73
-
74
- /**
75
- This method exists because collection view updates are throttled because of internal collection view bugs.
76
- Collection view behaves poorly during fast updates, so this should remedy those issues.
77
- */
78
- open func collectionView( _ collectionView: UICollectionView , throttledObservedEvent event: Event < Element > ) {
79
- Binder ( self ) { dataSource, newSections in
80
- let oldSections = dataSource. sectionModels
81
- do {
82
- // if view is not in view hierarchy, performing batch updates will crash the app
83
- if collectionView. window == nil {
84
- dataSource. setSections ( newSections)
85
- collectionView. reloadData ( )
86
- return
87
- }
88
- let differences = try Diff . differencesForSectionedView ( initialSections: oldSections, finalSections: newSections)
89
-
90
- switch self . decideViewTransition ( self , collectionView, differences) {
91
- case . animated:
92
- for difference in differences {
93
- dataSource. setSections ( difference. finalSections)
94
-
95
- collectionView. performBatchUpdates ( difference, animationConfiguration: self . animationConfiguration)
96
- }
97
- case . reload:
98
- self . setSections ( newSections)
99
- collectionView. reloadData ( )
100
- }
101
- }
102
- catch let e {
103
- #if DEBUG
104
- print ( " Error while binding data animated: \( e) \n Fallback to normal `reloadData` behavior. " )
105
- rxDebugFatalError ( e)
106
- #endif
107
- self . setSections ( newSections)
108
- collectionView. reloadData ( )
109
- }
110
- } . on ( event)
111
- }
112
-
113
52
open func collectionView( _ collectionView: UICollectionView , observedEvent: Event < Element > ) {
114
53
Binder ( self ) { dataSource, newSections in
115
54
#if DEBUG
@@ -121,8 +60,41 @@ open class RxCollectionViewSectionedAnimatedDataSource<S: AnimatableSectionModel
121
60
collectionView. reloadData ( )
122
61
}
123
62
else {
124
- let element = ( collectionView, observedEvent)
125
- dataSource. partialUpdateEvent. on ( . next( element) )
63
+ DispatchQueue . main. async {
64
+ // if view is not in view hierarchy, performing batch updates will crash the app
65
+ if collectionView. window == nil {
66
+ dataSource. setSections ( newSections)
67
+ collectionView. reloadData ( )
68
+ return
69
+ }
70
+ let oldSections = dataSource. sectionModels
71
+ do {
72
+ let differences = try Diff . differencesForSectionedView ( initialSections: oldSections, finalSections: newSections)
73
+
74
+ switch self . decideViewTransition ( self , collectionView, differences) {
75
+ case . animated:
76
+ // each difference must be run in a separate performBatchUpdate, otherwise it crashes.
77
+ // this is a limitation of Diff tool
78
+ for difference in differences {
79
+ collectionView. performBatchUpdates ( { [ unowned self] in
80
+ // sections must be set within updateBlock in performBatchUpdates
81
+ dataSource. setSections ( difference. finalSections)
82
+ collectionView. batchUpdates ( difference, animationConfiguration: self . animationConfiguration)
83
+ } , completion: nil )
84
+ }
85
+
86
+ case . reload:
87
+ self . setSections ( newSections)
88
+ collectionView. reloadData ( )
89
+ return
90
+ }
91
+ }
92
+ catch let e {
93
+ rxDebugFatalError ( e)
94
+ self . setSections ( newSections)
95
+ collectionView. reloadData ( )
96
+ }
97
+ }
126
98
}
127
99
} . on ( observedEvent)
128
100
}
0 commit comments