Skip to content

Commit da3787b

Browse files
authored
Merge pull request #29 from NicFontana/fix/rows-visibility-changes-delegate-calls
Fix: `ScrollStackControllerDelegate` methods calls
2 parents d07064e + 6213415 commit da3787b

File tree

2 files changed

+41
-21
lines changed

2 files changed

+41
-21
lines changed

Sources/ScrollStackController/ScrollStack.swift

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,8 @@ open class ScrollStack: UIScrollView, UIScrollViewDelegate {
860860
return createRow(newRow, at: index, cellToRemove: cellToRemove, animated: animated, completion: completion)
861861
}
862862

863+
private var rowVisibilityChangesDispatchWorkItem: DispatchWorkItem?
864+
863865
/// Private implementation to add new row.
864866
private func createRow(_ newRow: ScrollStackRow, at index: Int,
865867
cellToRemove: ScrollStackRow?,
@@ -878,7 +880,21 @@ open class ScrollStack: UIScrollView, UIScrollViewDelegate {
878880
}, completion: nil)
879881
}
880882

881-
scrollViewDidScroll(self)
883+
if rowVisibilityChangesDispatchWorkItem == nil {
884+
885+
rowVisibilityChangesDispatchWorkItem = DispatchWorkItem(block: { [weak self] in
886+
if let stackDelegate = self?.stackDelegate {
887+
self?.dispatchRowsVisibilityChangesTo(stackDelegate)
888+
}
889+
890+
self?.rowVisibilityChangesDispatchWorkItem = nil
891+
})
892+
893+
/// Schedule a single `dispatchRowsVisibilityChangesTo(_:)` call.
894+
///
895+
/// In this way, when rows are created inside a for-loop, the delegate is called only once after the `ScrollStack` has been fully laid out.
896+
DispatchQueue.main.async(execute: rowVisibilityChangesDispatchWorkItem!)
897+
}
882898

883899
return newRow
884900
}
@@ -979,25 +995,27 @@ open class ScrollStack: UIScrollView, UIScrollViewDelegate {
979995
}
980996

981997
private func dispatchRowsVisibilityChangesTo(_ delegate: ScrollStackControllerDelegate) {
982-
delegate.scrollStackDidScroll(self, offset: contentOffset)
983-
984998
rows.enumerated().forEach { (idx, row) in
985999
let current = isRowVisible(index: idx)
986-
if let previous = prevVisibilityState[row] {
987-
switch (previous, current) {
988-
case (.offscreen, .partial), // row will become invisible
989-
(.hidden, .partial),
990-
(.hidden, .entire):
991-
delegate.scrollStackRowDidBecomeVisible(self, row: row, index: idx, state: current)
992-
993-
case (.partial, .offscreen), // row will become visible
994-
(.partial, .hidden),
995-
(.entire, .hidden):
996-
delegate.scrollStackRowDidBecomeHidden(self, row: row, index: idx, state: current)
997-
998-
default:
999-
break
1000-
}
1000+
let previous = prevVisibilityState[row]
1001+
1002+
switch (previous, current) {
1003+
case (.offscreen, .partial), // row will become visible
1004+
(nil, .entire),
1005+
(nil, .partial),
1006+
(.partial, .entire),
1007+
(.hidden, .partial),
1008+
(.hidden, .entire):
1009+
delegate.scrollStackRowDidBecomeVisible(self, row: row, index: idx, state: current)
1010+
1011+
case (.partial, .offscreen), // row will become invisible
1012+
(.entire, .partial),
1013+
(.partial, .hidden),
1014+
(.entire, .hidden):
1015+
delegate.scrollStackRowDidBecomeHidden(self, row: row, index: idx, state: current)
1016+
1017+
default:
1018+
break
10011019
}
10021020

10031021
// store previous state
@@ -1062,7 +1080,8 @@ open class ScrollStack: UIScrollView, UIScrollViewDelegate {
10621080
guard let stackDelegate = stackDelegate else {
10631081
return
10641082
}
1065-
1083+
stackDelegate.scrollStackDidScroll(self, offset: contentOffset)
1084+
10661085
dispatchRowsVisibilityChangesTo(stackDelegate)
10671086
}
10681087

Sources/ScrollStackController/ScrollStackRow.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,11 @@ open class ScrollStackRow: UIView, UIGestureRecognizerDelegate {
239239
setNeedsUpdateConstraints()
240240
}
241241

242-
open override func layoutSubviews() {
243-
super.layoutSubviews()
242+
open override func updateConstraints() {
244243
// called the event to update the height of the row.
245244
askForCutomizedSizeOfContentView(animated: false)
245+
246+
super.updateConstraints()
246247
}
247248

248249
private func applyParentStackAttributes() {

0 commit comments

Comments
 (0)