@@ -96,6 +96,7 @@ extension ForEach: TypeSafeView, View where Child: View {
9696
9797 var layoutableChildren : [ LayoutSystem . LayoutableChild ] = [ ]
9898
99+ let oldNodes = children. nodes
99100 let oldMap = children. nodeIdentifierMap
100101 let oldIdentifiers = children. identifiers
101102 let identifiersStart = oldIdentifiers. startIndex
@@ -108,52 +109,63 @@ extension ForEach: TypeSafeView, View where Child: View {
108109 // still exists in the new one is reinserted to ensure that items are
109110 // rendered in the correct order.
110111 var requiresOngoingReinsertion = false
112+ var ongoingNodeReusingDisabled = false
113+ var inserted = false
111114
112115 for element in elements {
113116 let childContent = child ( element)
114117 let node : AnyViewGraphNode < Child >
115118
116- if let oldNode = oldMap [ element [ keyPath: idKeyPath] ] {
117- node = oldNode
118-
119- // Checks if there is a preceding item that was not preceding in
120- // the previous update. If such an item exists, it means that
121- // the order of the collection has changed or that an item was
122- // inserted somewhere in the middle, rather than simply appended.
123- requiresOngoingReinsertion =
124- requiresOngoingReinsertion
125- || {
126- guard
127- let ownOldIndex = oldIdentifiers. firstIndex (
128- of: element [ keyPath: idKeyPath] )
129- else { return false }
130-
131- let subset = oldIdentifiers [ identifiersStart..< ownOldIndex]
132- return !children. identifiers. subtracting ( subset) . isEmpty
133- } ( )
134-
135- if requiresOngoingReinsertion {
136- removeChild ( oldNode. widget. into ( ) )
137- addChild ( oldNode. widget. into ( ) )
119+ ( inserted, _) = children. identifiers. append ( element [ keyPath: idKeyPath] )
120+ ongoingNodeReusingDisabled = ongoingNodeReusingDisabled || !inserted
121+
122+ if !ongoingNodeReusingDisabled {
123+ if let oldNode = oldMap [ element [ keyPath: idKeyPath] ] {
124+ node = oldNode
125+
126+ // Checks if there is a preceding item that was not preceding in
127+ // the previous update. If such an item exists, it means that
128+ // the order of the collection has changed or that an item was
129+ // inserted somewhere in the middle, rather than simply appended.
130+ requiresOngoingReinsertion =
131+ requiresOngoingReinsertion
132+ || {
133+ guard
134+ let ownOldIndex = oldIdentifiers. firstIndex (
135+ of: element [ keyPath: idKeyPath] )
136+ else { return false }
137+
138+ let subset = oldIdentifiers [ identifiersStart..< ownOldIndex]
139+ return !children. identifiers. subtracting ( subset) . isEmpty
140+ } ( )
141+
142+ if requiresOngoingReinsertion {
143+ removeChild ( oldNode. widget. into ( ) )
144+ addChild ( oldNode. widget. into ( ) )
145+ }
146+ } else {
147+ // New Items need ongoing reinsertion to get
148+ // displayed at the correct locat ion.
149+ requiresOngoingReinsertion = true
150+ node = AnyViewGraphNode (
151+ for: childContent,
152+ backend: backend,
153+ environment: environment
154+ )
155+ addChild ( node. widget. into ( ) )
138156 }
157+ children. nodeIdentifierMap [ element [ keyPath: idKeyPath] ] = node
139158 } else {
140- // New Items need ongoing reinsertion to get
141- // displayed at the correct locat ion.
142- requiresOngoingReinsertion = true
143159 node = AnyViewGraphNode (
144160 for: childContent,
145161 backend: backend,
146162 environment: environment
147163 )
148- addChild ( node. widget. into ( ) )
149164 }
150165
151- children. nodeIdentifierMap [ element [ keyPath: idKeyPath] ] = node
152- children. identifiers. append ( element [ keyPath: idKeyPath] )
153-
154166 children. nodes. append ( node)
155167
156- if children. isFirstUpdate {
168+ if children. isFirstUpdate, !ongoingNodeReusingDisabled {
157169 addChild ( node. widget. into ( ) )
158170 }
159171
@@ -173,10 +185,19 @@ extension ForEach: TypeSafeView, View where Child: View {
173185
174186 children. isFirstUpdate = false
175187
176- for removed in oldMap. filter ( {
177- !children. identifiers. contains ( $0. key)
178- } ) . values {
179- removeChild ( removed. widget. into ( ) )
188+ if !ongoingNodeReusingDisabled {
189+ for removed in oldMap. filter ( {
190+ !children. identifiers. contains ( $0. key)
191+ } ) . values {
192+ removeChild ( removed. widget. into ( ) )
193+ }
194+ } else {
195+ for nodeToRemove in oldNodes {
196+ removeChild ( nodeToRemove. widget. into ( ) )
197+ }
198+ for nodeToAdd in children. nodes {
199+ addChild ( nodeToAdd. widget. into ( ) )
200+ }
180201 }
181202
182203 return LayoutSystem . updateStackLayout (
0 commit comments