Skip to content

Commit e8af740

Browse files
committed
composer efficiency
1 parent 1e06bf1 commit e8af740

1 file changed

Lines changed: 31 additions & 41 deletions

File tree

Sources/Provider/CollectionComposer.swift

Lines changed: 31 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,34 @@ import UIKit
1111
open class CollectionComposer: BaseCollectionProvider {
1212

1313
public var sections: [AnyCollectionProvider] {
14+
get { return dataProvider.data }
15+
set { dataProvider.data = newValue }
16+
}
17+
18+
public var presenter: CollectionPresenter? {
1419
didSet {
1520
setNeedsReload()
1621
}
1722
}
1823

19-
fileprivate var sectionBeginIndex: [Int] = []
20-
fileprivate var sectionForIndex: [Int] = []
21-
22-
fileprivate var currentSections: [AnyCollectionProvider] = []
23-
24-
public var presenter: CollectionPresenter? { didSet { setNeedsReload() } }
25-
2624
public var layout: CollectionLayout<AnyCollectionProvider> {
2725
didSet {
2826
setNeedsReload()
2927
}
3028
}
3129

30+
private var sectionBeginIndex: [Int] = []
31+
private var dataProvider: ArrayDataProvider<AnyCollectionProvider>
32+
3233
public init(identifier: String? = nil,
3334
layout: CollectionLayout<AnyCollectionProvider> = FlowLayout(),
3435
presenter: CollectionPresenter? = nil,
3536
sections: [AnyCollectionProvider]) {
36-
self.sections = sections
3737
self.presenter = presenter
3838
self.layout = layout
39+
self.dataProvider = ArrayDataProvider(data: sections, identifierMapper: {
40+
return $1.identifier ?? "\($0)"
41+
})
3942
super.init(identifier: identifier)
4043
}
4144

@@ -47,37 +50,34 @@ open class CollectionComposer: BaseCollectionProvider {
4750
}
4851

4952
func indexPath(_ index: Int) -> (Int, Int) {
50-
let section = sectionForIndex[index]
51-
let item = index - sectionBeginIndex[section]
52-
return (section, item)
53+
let sectionIndex = sectionBeginIndex.binarySearch { $0 <= index } - 1
54+
return (sectionIndex, index - sectionBeginIndex[sectionIndex])
5355
}
5456

5557
open override var numberOfItems: Int {
56-
return sectionForIndex.count
58+
return (sectionBeginIndex.last ?? 0) + (sections.last?.numberOfItems ?? 0)
5759
}
5860

5961
open override func view(at: Int) -> UIView {
6062
let (sectionIndex, item) = indexPath(at)
61-
return currentSections[sectionIndex].view(at: item)
63+
return sections[sectionIndex].view(at: item)
6264
}
6365

6466
open override func update(view: UIView, at: Int) {
6567
let (sectionIndex, item) = indexPath(at)
66-
currentSections[sectionIndex].update(view: view, at: item)
68+
sections[sectionIndex].update(view: view, at: item)
6769
}
6870

6971
open override func identifier(at: Int) -> String {
7072
let (sectionIndex, item) = indexPath(at)
71-
let sectionIdentifier = currentSections[sectionIndex].identifier ?? "\(sectionIndex)"
72-
return "\(sectionIdentifier)." + currentSections[sectionIndex].identifier(at: item)
73+
let sectionIdentifier = sections[sectionIndex].identifier ?? "\(sectionIndex)"
74+
return "\(sectionIdentifier)." + sections[sectionIndex].identifier(at: item)
7375
}
7476

7577
open override func layout(collectionSize: CGSize) {
7678
layout.layout(
7779
collectionSize: collectionSize,
78-
dataProvider: ArrayDataProvider(data: currentSections, identifierMapper: {
79-
return $1.identifier ?? "\($0)"
80-
}),
80+
dataProvider: dataProvider,
8181
sizeProvider: { (_, data, collectionSize) in
8282
data.layout(collectionSize: collectionSize)
8383
return data.contentSize
@@ -94,7 +94,7 @@ open class CollectionComposer: BaseCollectionProvider {
9494
let sectionFrame = layout.frame(at: sectionIndex)
9595
let intersectFrame = visibleFrame.intersection(sectionFrame)
9696
let visibleFrameForCell = CGRect(origin: intersectFrame.origin - sectionFrame.origin, size: intersectFrame.size)
97-
let sectionVisible = currentSections[sectionIndex].visibleIndexes(visibleFrame: visibleFrameForCell)
97+
let sectionVisible = sections[sectionIndex].visibleIndexes(visibleFrame: visibleFrameForCell)
9898
let beginIndex = sectionBeginIndex[sectionIndex]
9999
for item in sectionVisible {
100100
visible.append(item + beginIndex)
@@ -105,14 +105,14 @@ open class CollectionComposer: BaseCollectionProvider {
105105

106106
open override func frame(at: Int) -> CGRect {
107107
let (sectionIndex, item) = indexPath(at)
108-
var frame = currentSections[sectionIndex].frame(at: item)
108+
var frame = sections[sectionIndex].frame(at: item)
109109
frame.origin += layout.frame(at: sectionIndex).origin
110110
return frame
111111
}
112112

113113
open override func presenter(at: Int) -> CollectionPresenter? {
114114
let (sectionIndex, item) = indexPath(at)
115-
return currentSections[sectionIndex].presenter(at: item) ?? presenter
115+
return sections[sectionIndex].presenter(at: item) ?? presenter
116116
}
117117

118118
open override func willReload() {
@@ -124,39 +124,29 @@ open class CollectionComposer: BaseCollectionProvider {
124124
}
125125

126126
internal func prepareForReload() {
127-
currentSections = sections
128127
sectionBeginIndex = []
129-
sectionForIndex = []
130-
sectionBeginIndex.reserveCapacity(currentSections.count)
131-
for (sectionIndex, section) in currentSections.enumerated() {
132-
let itemCount = section.numberOfItems
133-
sectionBeginIndex.append(sectionForIndex.count)
134-
for _ in 0..<itemCount {
135-
sectionForIndex.append(sectionIndex)
136-
}
128+
sectionBeginIndex.reserveCapacity(sections.count)
129+
var count = 0
130+
for section in sections {
131+
sectionBeginIndex.append(count)
132+
count += section.numberOfItems
137133
}
138134
}
139135

140136
open override func didReload() {
141137
super.didReload()
142-
for section in currentSections {
138+
for section in sections {
143139
section.didReload()
144140
}
145141
}
146142

147143
open override func didTap(view: UIView, at: Int) {
148144
let (sectionIndex, item) = indexPath(at)
149-
currentSections[sectionIndex].didTap(view: view, at: item)
145+
sections[sectionIndex].didTap(view: view, at: item)
150146
}
151147

152148
open override func hasReloadable(_ reloadable: CollectionReloadable) -> Bool {
153-
if reloadable === self { return true }
154-
for section in currentSections {
155-
if section.hasReloadable(reloadable) {
156-
return true
157-
}
158-
}
159-
return false
149+
return reloadable === self || reloadable === dataProvider ||
150+
sections.contains(where: { $0.hasReloadable(reloadable) })
160151
}
161-
162152
}

0 commit comments

Comments
 (0)