@@ -23,6 +23,7 @@ final class LoadingState {
2323 private var delayedCountByTarget : [ AnyHashable : Int ] = [ : ]
2424 private var delayedTaskByTarget : [ AnyHashable : Task < Void , Never > ] = [ : ]
2525 private var visibleDelayedTargets = Set < AnyHashable > ( )
26+ private var visibleTargets = Set < AnyHashable > ( )
2627
2728 init ( delay: Duration = . milliseconds( 500 ) ) {
2829 self . delay = delay
@@ -76,7 +77,7 @@ final class LoadingState {
7677 switch mode {
7778 case . immediate:
7879 immediateCountByTarget [ target, default: 0 ] += 1
79- update ( true )
80+ setVisibilityIfNeeded ( for : target , isVisible : true , update : update )
8081 case . delayed:
8182 delayedCountByTarget [ target, default: 0 ] += 1
8283 scheduleDelayedLoadingIfNeeded ( for: target, update: update)
@@ -115,7 +116,7 @@ final class LoadingState {
115116 guard 0 < self . delayedCountByTarget [ target, default: 0 ] else { return }
116117 self . visibleDelayedTargets. insert ( target)
117118 if self . immediateCountByTarget [ target, default: 0 ] == 0 {
118- update ( true )
119+ self . setVisibilityIfNeeded ( for : target , isVisible : true , update : update )
119120 }
120121 }
121122 }
@@ -126,25 +127,47 @@ final class LoadingState {
126127 update: @escaping @MainActor ( Bool ) -> Void
127128 ) {
128129 if 0 < immediateCountByTarget [ target, default: 0 ] {
129- update ( true )
130+ setVisibilityIfNeeded ( for : target , isVisible : true , update : update )
130131 return
131132 }
132133 if visibleDelayedTargets. contains ( target) {
133134 if delayedCountByTarget [ target, default: 0 ] == 0 {
134135 visibleDelayedTargets. remove ( target)
135- update ( false )
136+ setVisibilityIfNeeded ( for : target , isVisible : false , update : update )
136137 } else {
137- update ( true )
138+ setVisibilityIfNeeded ( for : target , isVisible : true , update : update )
138139 }
139140 return
140141 }
141142 if 0 < delayedCountByTarget [ target, default: 0 ] {
142- update ( false )
143+ if visibleTargets. contains ( target) {
144+ setVisibilityIfNeeded ( for: target, isVisible: true , update: update)
145+ } else {
146+ setVisibilityIfNeeded ( for: target, isVisible: false , update: update)
147+ }
143148 scheduleDelayedLoadingIfNeeded ( for: target, update: update)
144149 return
145150 }
146151 delayedTaskByTarget [ target] ? . cancel ( )
147152 delayedTaskByTarget [ target] = nil
148- update ( false )
153+ setVisibilityIfNeeded ( for: target, isVisible: false , update: update)
154+ }
155+
156+ private func setVisibilityIfNeeded(
157+ for target: AnyHashable ,
158+ isVisible: Bool ,
159+ update: @escaping @MainActor ( Bool ) -> Void
160+ ) {
161+ let wasVisible = visibleTargets. contains ( target)
162+
163+ if isVisible {
164+ visibleTargets. insert ( target)
165+ } else {
166+ visibleTargets. remove ( target)
167+ }
168+
169+ if wasVisible != isVisible {
170+ update ( isVisible)
171+ }
149172 }
150173}
0 commit comments