@@ -86,7 +86,159 @@ private struct DynamicLayoutViewChildGeometry: StatefulRule, AsyncAttribute {
8686 }
8787}
8888
89- // TODO: - DynamicLayoutViewAdaptor
89+ // MARK: - DynamicLayoutViewAdaptor [WIP] ContentTransition
90+
91+ struct DynamicLayoutViewAdaptor : DynamicContainerAdaptor {
92+ private struct MakeTransition : TransitionVisitor {
93+ var containerInfo : Attribute < DynamicContainer . Info >
94+ var uniqueId : UInt32
95+ var item : DynamicViewListItem
96+ var inputs : _ViewInputs
97+ var makeElt : ( _ViewInputs ) -> _ViewOutputs
98+ var outputs : _ViewOutputs ?
99+ var isArchived : Bool
100+
101+ mutating func visit< T> ( _ transition: T ) where T: Transition {
102+ let helper = TransitionHelper (
103+ list: . init( item. list) ,
104+ info: containerInfo,
105+ uniqueID: uniqueId,
106+ transition: transition,
107+ phase: . identity
108+ )
109+ if isArchived {
110+ makeArchivedTransition ( helper: helper)
111+ } else {
112+ let transition = Attribute (
113+ ViewListTransition ( helper: helper)
114+ )
115+ let makeElt = self . makeElt
116+ outputs = T . makeView (
117+ view: . init( transition) ,
118+ inputs: inputs,
119+ body: { _, inputs in
120+ makeElt ( inputs)
121+ }
122+ )
123+ }
124+ }
125+
126+ mutating func makeArchivedTransition< T> ( helper: TransitionHelper < T > ) where T: Transition {
127+ guard helper. transition. hasContentTransition else {
128+ outputs = makeElt ( inputs)
129+ return
130+ }
131+ // TODO: archived transition
132+ _openSwiftUIUnimplementedFailure ( )
133+ }
134+ }
135+
136+ struct ItemLayout {
137+ var release : ViewList . Elements . Release ?
138+ }
139+
140+ @Attribute var items : ViewList
141+ @OptionalAttribute var childGeometries : [ ViewGeometry ] ?
142+ var mutateLayoutMap : ( ( inout DynamicLayoutMap ) -> ( ) ) -> ( )
143+
144+ func updatedItems( ) -> ViewList ? {
145+ let ( items, itemsChanged) = $items. changedValue ( )
146+ guard itemsChanged else {
147+ return nil
148+ }
149+ return items
150+ }
151+
152+ func foreachItem(
153+ items: any ViewList ,
154+ _ body: ( DynamicViewListItem ) -> Void
155+ ) {
156+ var index = 0
157+ items. applySublists ( from: & index, list: $items) { sublist in
158+ body ( . init(
159+ id: sublist. id,
160+ elements: sublist. elements,
161+ traits: sublist. traits,
162+ list: sublist. list
163+ ) )
164+ return true
165+ }
166+ }
167+
168+ static func containsItem(
169+ _ items: any ViewList ,
170+ _ item: DynamicViewListItem
171+ ) -> Bool {
172+ var index = 0
173+ let result = items. applySublists ( from: & index, list: nil ) { sublist in
174+ sublist. id != item. id
175+ }
176+ return !result
177+ }
178+
179+ func makeItemLayout(
180+ item: DynamicViewListItem ,
181+ uniqueId: UInt32 ,
182+ inputs: _ViewInputs ,
183+ containerInfo: Attribute < DynamicContainer . Info > ,
184+ containerInputs: ( inout _ViewInputs ) -> ( )
185+ ) -> ( _ViewOutputs , DynamicLayoutViewAdaptor . ItemLayout ) {
186+ let isArchived = inputs. archivedView. isArchived
187+ let traits = item. traits
188+ let transition : AnyTransition ?
189+ if let t = traits. optionalTransition ( ignoringIdentity: !isArchived) {
190+ let prefersCrossFadeTransitions = Graph . withoutUpdate {
191+ inputs. environment. value. accessibilityPrefersCrossFadeTransitions
192+ }
193+ transition = t. adjustedForAccessibility ( prefersCrossFade: prefersCrossFadeTransitions)
194+ } else {
195+ transition = nil
196+ }
197+ var containerID = DynamicContainerID ( uniqueId: uniqueId, viewIndex: 0 )
198+ let outputs = item. elements. makeAllElements ( inputs: inputs) { elementInputs, body in
199+ var elementInputs = elementInputs
200+ if elementInputs. needsGeometry {
201+ let childGeometry = Attribute (
202+ DynamicLayoutViewChildGeometry (
203+ containerInfo: containerInfo,
204+ childGeometries: $childGeometries!,
205+ id: containerID
206+ )
207+ )
208+ elementInputs. size = childGeometry. size ( )
209+ elementInputs. position = childGeometry. origin ( )
210+ }
211+ let outputs : _ViewOutputs
212+ if let transition {
213+ var makeTransition = MakeTransition (
214+ containerInfo: containerInfo,
215+ uniqueId: uniqueId,
216+ item: item,
217+ inputs: elementInputs,
218+ makeElt: body,
219+ isArchived: isArchived
220+ )
221+ transition. visitBase ( applying: & makeTransition)
222+ outputs = makeTransition. outputs!
223+ } else {
224+ outputs = body ( elementInputs)
225+ }
226+ mutateLayoutMap ( {
227+ $0 [ containerID] = LayoutProxyAttributes (
228+ layoutComputer: . init( outputs. layoutComputer) ,
229+ traitsList: . init( item. list)
230+ )
231+ } )
232+ containerID. viewIndex &+= 1
233+ return outputs
234+ }
235+ return ( outputs ?? . init( ) , . init( release: item. elements. retain ( ) ) )
236+ }
237+
238+ func removeItemLayout( uniqueId: UInt32 , itemLayout: ItemLayout ) {
239+ mutateLayoutMap ( { $0. remove ( uniqueId: uniqueId) } )
240+ }
241+ }
90242
91243// MARK: - DynamicLayoutComputer
92244
0 commit comments