@@ -239,7 +239,7 @@ private struct DynamicPreferenceCombiner<K>: Rule, AsyncAttribute, CustomStringC
239239 }
240240}
241241
242- // MARK: - DynamicContainerInfo [WIP]
242+ // MARK: - DynamicContainerInfo
243243
244244struct DynamicContainerInfo < Adapter> : StatefulRule , AsyncAttribute , ObservedAttribute , CustomStringConvertible where Adapter: DynamicContainerAdaptor {
245245 @Attribute var asyncSignal : Void
@@ -582,37 +582,34 @@ struct DynamicContainerInfo<Adapter>: StatefulRule, AsyncAttribute, ObservedAttr
582582 at index: Int ,
583583 disableTransitions: Bool
584584 ) -> Bool {
585- let items = info. items
586- guard let phase = items [ index] . phase else {
585+ guard let phase = info. items [ index] . phase else {
587586 return false
588587 }
589588 switch phase {
590589 case . willAppear:
591590 preconditionFailure ( " " )
592591 case . identity:
593- guard !disableTransitions, items [ index] . needsTransitions else {
592+ guard !disableTransitions, info . items [ index] . needsTransitions else {
594593 eraseItem ( at: index)
595594 return true
596595 }
597596 lastRemoved = max ( lastRemoved &+ 1 , 1 )
598- items [ index] . removalOrder = lastRemoved
597+ info . items [ index] . removalOrder = lastRemoved
599598 info. removedCount &+= 1
600- items [ index] . phase = . didDisappear
601- if let listener = items [ index] . listener {
602- listener. viewGraph = nil
603- }
599+ info. items [ index] . phase = . didDisappear
600+ info. items [ index] . listener? . viewGraph = nil
604601 let newListener = DynamicAnimationListener (
605602 viewGraph: . current,
606603 asyncSignal: WeakAttribute ( $asyncSignal)
607604 )
608- items [ index] . listener = newListener
605+ info . items [ index] . listener = newListener
609606 newListener. animationWasAdded ( )
610607 Update . enqueueAction { // TODO: reason
611608 newListener. animationWasRemoved ( )
612609 }
613610 return false
614611 case . didDisappear:
615- let listener = items [ index] . listener!
612+ let listener = info . items [ index] . listener!
616613 guard listener. count == 0 else {
617614 return false
618615 }
@@ -622,25 +619,24 @@ struct DynamicContainerInfo<Adapter>: StatefulRule, AsyncAttribute, ObservedAttr
622619 }
623620
624621 mutating func unremoveItem( at index: Int ) {
625- let items = info. items
626622 let phase : TransitionPhase
627- switch items [ index] . phase {
623+ switch info . items [ index] . phase {
628624 case . willAppear, . identity:
629- items [ index] . resetSeed &-= 1
625+ info . items [ index] . resetSeed &-= 1
630626 phase = . identity
631627 case . didDisappear:
632628 info. removedCount &-= 1
633- items [ index] . removalOrder = 0
629+ info . items [ index] . removalOrder = 0
634630 phase = . identity
635631 case nil :
636632 info. unusedCount &-= 1
637- let subgraph = items [ index] . subgraph
633+ let subgraph = info . items [ index] . subgraph
638634 parentSubgraph. addChild ( subgraph)
639635 subgraph. didReinsert ( )
640636 phase = . willAppear
641637 }
642- let newPhase = items [ index] . needsTransitions ? phase : . identity
643- items [ index] . phase = newPhase
638+ let newPhase = info . items [ index] . needsTransitions ? phase : . identity
639+ info . items [ index] . phase = newPhase
644640 guard newPhase == . willAppear else {
645641 return
646642 }
@@ -654,11 +650,44 @@ struct DynamicContainerInfo<Adapter>: StatefulRule, AsyncAttribute, ObservedAttr
654650 }
655651 }
656652
657- func eraseItem( at index: Int ) {
658- _openSwiftUIUnimplementedWarning ( )
653+ mutating func eraseItem( at index: Int ) {
654+ let phase = info. items [ index] . phase
655+ switch phase {
656+ case . identity, nil :
657+ preconditionFailure ( " " )
658+ case . willAppear:
659+ break
660+ case . didDisappear:
661+ info. removedCount &-= 1
662+ }
663+ let unusedCount = info. unusedCount
664+ let maxUnusedItems = Adapter . maxUnusedItems
665+ let subgraph = info. items [ index] . subgraph
666+ let item = info. items [ index] . for ( Adapter . self)
667+ if unusedCount < maxUnusedItems {
668+ info. items. remove ( at: index)
669+ item. removalOrder = 0
670+ item. resetSeed &+= 1
671+ item. phase = nil
672+ item. listener? . viewGraph = nil
673+ item. listener = nil
674+ info. items. append ( item)
675+ info. unusedCount = unusedCount &+ 1
676+ subgraph. willRemove ( )
677+ parentSubgraph. removeChild ( subgraph)
678+ } else {
679+ adaptor. removeItemLayout (
680+ uniqueId: item. uniqueId,
681+ itemLayout: item. itemLayout
682+ )
683+ item. listener? . viewGraph = nil
684+ info. items. remove ( at: index)
685+ subgraph. willInvalidate ( isInserted: true )
686+ subgraph. invalidate ( )
687+ }
659688 }
660689
661- // DynamicPreferenceCombiner + ObservedAttribute
690+ // MARK: - DynamicContainerInfo + ObservedAttribute
662691
663692 mutating func destroy( ) {
664693 for item in info. items {
@@ -671,7 +700,7 @@ struct DynamicContainerInfo<Adapter>: StatefulRule, AsyncAttribute, ObservedAttr
671700 }
672701 }
673702
674- // DynamicPreferenceCombiner + CustomStringConvertible
703+ // MARK: - DynamicContainerInfo + CustomStringConvertible
675704
676705 var description : String {
677706 " DynamicContainer< \( Adapter . self) > "
0 commit comments