11//
22// ViewTrait.swift
3- // OpenSwiftUI
3+ // OpenSwiftUICore
44//
55// Audited for iOS 18.0
6- // Status: Blocked by ViewList
6+ // Status: Complete
77// ID: 9929B476764059557433A108298EE66F (SwiftUI)
88// ID: 48526BA25CDCBF890FA91D018A5421B4 (SwiftUICore)
99
10- // TODO: Update path and fix the ViewList issue and the TODO
11-
1210import OpenGraphShims
1311
1412// MARK: - ViewTraitKey
@@ -23,11 +21,11 @@ public protocol _ViewTraitKey {
2321 static var defaultValue : Value { get }
2422}
2523
26- // MARK: - _TraitWritingModifier [TODO]
24+ // MARK: - _TraitWritingModifier
2725
2826/// A view content adapter that associates a trait with its base content.
2927@frozen
30- public struct _TraitWritingModifier < Trait> : PrimitiveViewModifier where Trait : _ViewTraitKey {
28+ public struct _TraitWritingModifier < Trait> : PrimitiveViewModifier where Trait: _ViewTraitKey {
3129 public let value : Trait . Value
3230
3331 @inlinable
@@ -40,23 +38,47 @@ public struct _TraitWritingModifier<Trait>: PrimitiveViewModifier where Trait :
4038 inputs: _ViewInputs ,
4139 body: @escaping ( _Graph , _ViewInputs ) -> _ViewOutputs
4240 ) -> _ViewOutputs {
43- preconditionFailure ( " TODO " )
41+ if Trait . self == LayoutPriorityTraitKey . self {
42+ LayoutPriorityLayout . makeViewImpl (
43+ modifier: modifier. unsafeCast ( ) ,
44+ inputs: inputs,
45+ body: body
46+ )
47+ } else {
48+ body ( _Graph ( ) , inputs)
49+ }
4450 }
51+
4552 nonisolated public static func _makeViewList(
4653 modifier: _GraphValue < Self > ,
4754 inputs: _ViewListInputs ,
4855 body: @escaping ( _Graph , _ViewListInputs ) -> _ViewListOutputs
4956 ) -> _ViewListOutputs {
50- preconditionFailure ( " TODO " )
51- }
52-
53- nonisolated public static func _viewListCount( inputs: _ViewListCountInputs , body: ( _ViewListCountInputs ) -> Int ? ) -> Int ? {
54- preconditionFailure ( " TODO " )
57+ var inputs = inputs
58+ if Trait . self == LayoutPriorityTraitKey . self,
59+ !inputs. options. contains ( . layoutPriorityIsTrait) {
60+ let attribute = modifier. value. unsafeBitCast ( to: _TraitWritingModifier< LayoutPriorityTraitKey> . self )
61+ var outputs = body ( _Graph ( ) , inputs)
62+ outputs. multiModifier ( _GraphValue ( attribute) , inputs: inputs)
63+ return outputs
64+ } else {
65+ let addTrait = AddTrait ( modifier: modifier. value, traits: OptionalAttribute ( inputs. traits) )
66+ let attribute = Attribute ( addTrait)
67+ inputs. addTraitKey ( Trait . self)
68+ inputs. traits = attribute
69+ return body ( _Graph ( ) , inputs)
70+ }
5571 }
5672
57- private struct AddTrait {
73+ private struct AddTrait : Rule {
5874 @Attribute var modifier : _TraitWritingModifier
5975 @OptionalAttribute var traits : ViewTraitCollection ?
76+
77+ var value : ViewTraitCollection {
78+ var traits = traits ?? ViewTraitCollection ( )
79+ traits [ Trait . self] = modifier. value
80+ return traits
81+ }
6082 }
6183}
6284
@@ -67,16 +89,17 @@ extension View {
6789 /// Associate a trait `value` for the given `key` for this view content.
6890 @inlinable
6991 nonisolated public func _trait< K> ( _ key: K . Type , _ value: K . Value ) -> some View where K: _ViewTraitKey {
70- return modifier ( _TraitWritingModifier < K > ( value: value) )
92+ modifier ( _TraitWritingModifier < K > ( value: value) )
7193 }
7294}
7395
74- // MARK: - _ConditionalTraitWritingModifier [TODO]
96+ // MARK: - _ConditionalTraitWritingModifier
7597
7698/// Conditionally writes a trait.
7799@frozen
78100public struct _ConditionalTraitWritingModifier < Trait> : PrimitiveViewModifier where Trait : _ViewTraitKey {
79101 public var value : Trait . Value
102+
80103 public var isEnabled : Bool
81104
82105 @_alwaysEmitIntoClient
@@ -90,26 +113,56 @@ public struct _ConditionalTraitWritingModifier<Trait>: PrimitiveViewModifier whe
90113 inputs: _ViewInputs ,
91114 body: @escaping ( _Graph , _ViewInputs ) -> _ViewOutputs
92115 ) -> _ViewOutputs {
93- preconditionFailure ( " TODO " )
116+ _TraitWritingModifier< Trait> . _makeView(
117+ modifier: _GraphValue ( . init( identifier: . nil ) ) ,
118+ inputs: inputs,
119+ body: body
120+ )
94121 }
122+
95123 nonisolated public static func _makeViewList(
96124 modifier: _GraphValue < Self > ,
97125 inputs: _ViewListInputs ,
98126 body: @escaping ( _Graph , _ViewListInputs ) -> _ViewListOutputs
99127 ) -> _ViewListOutputs {
100- preconditionFailure ( " TODO " )
128+ var inputs = inputs
129+ if Trait . self == LayoutPriorityTraitKey . self,
130+ !inputs. options. contains ( . layoutPriorityIsTrait) {
131+ let attribute = modifier. value. unsafeBitCast ( to: _TraitWritingModifier< LayoutPriorityTraitKey> . self )
132+ var outputs = body ( _Graph ( ) , inputs)
133+ outputs. multiModifier ( _GraphValue ( attribute) , inputs: inputs)
134+ return outputs
135+ } else {
136+ let addTrait = ConditionalAddTrait ( modifier: modifier. value, traits: OptionalAttribute ( inputs. traits) )
137+ let attribute = Attribute ( addTrait)
138+ inputs. addTraitKey ( Trait . self)
139+ inputs. traits = attribute
140+ return body ( _Graph ( ) , inputs)
141+ }
101142 }
102143
103- nonisolated public static func _viewListCount( inputs: _ViewListCountInputs , body: ( _ViewListCountInputs ) -> Int ? ) -> Int ? {
104- preconditionFailure ( " TODO " )
144+ private struct ConditionalAddTrait : Rule {
145+ @Attribute var modifier : _ConditionalTraitWritingModifier
146+ @OptionalAttribute var traits : ViewTraitCollection ?
147+
148+ var value : ViewTraitCollection {
149+ var traits = traits ?? ViewTraitCollection ( )
150+ if modifier. isEnabled {
151+ traits [ Trait . self] = modifier. value
152+ }
153+ return traits
154+ }
105155 }
106156}
107157
108158@available ( * , unavailable)
109159extension _ConditionalTraitWritingModifier : Sendable { }
110160
111161extension View {
162+ /// Conditionally writes a trait.
112163 @_alwaysEmitIntoClient
164+ @MainActor
165+ @preconcurrency
113166 public func _trait< K> ( _ key: K . Type = K . self, _ value: K . Value , isEnabled: Bool ) -> some View where K: _ViewTraitKey {
114167 modifier ( _ConditionalTraitWritingModifier < K > (
115168 value: value,
@@ -118,15 +171,49 @@ extension View {
118171 }
119172}
120173
121- // MARK: - TraitTransformerModifier [TODO]
174+ // MARK: - TraitTransformerModifier
122175
123- struct TraitTransformerModifier {
124-
176+ struct TraitTransformerModifier < Trait> : PrimitiveViewModifier where Trait: _ViewTraitKey {
177+ var transform : ( inout Trait . Value ) -> Void
178+
179+ nonisolated public static func _makeView(
180+ modifier: _GraphValue < Self > ,
181+ inputs: _ViewInputs ,
182+ body: @escaping ( _Graph , _ViewInputs ) -> _ViewOutputs
183+ ) -> _ViewOutputs {
184+ body ( _Graph ( ) , inputs)
185+ }
186+
187+ nonisolated public static func _makeViewList(
188+ modifier: _GraphValue < Self > ,
189+ inputs: _ViewListInputs ,
190+ body: @escaping ( _Graph , _ViewListInputs ) -> _ViewListOutputs
191+ ) -> _ViewListOutputs {
192+ var inputs = inputs
193+ let trait = TransformTrait ( modifier: modifier. value, traits: OptionalAttribute ( inputs. traits) )
194+ let attribute = Attribute ( trait)
195+ inputs. traits = attribute
196+ return body ( _Graph ( ) , inputs)
197+ }
198+
199+ private struct TransformTrait : Rule {
200+ @Attribute var modifier : TraitTransformerModifier
201+ @OptionalAttribute var traits : ViewTraitCollection ?
202+
203+ var value : ViewTraitCollection {
204+ var traits = traits ?? ViewTraitCollection ( )
205+ let transform = modifier. transform
206+ var value = traits. value ( for: Trait . self)
207+ transform ( & value)
208+ traits [ Trait . self] = value
209+ return traits
210+ }
211+ }
125212}
126213
127214extension View {
128215 package func transformTrait< K> ( _ key: K . Type = K . self, transform: @escaping ( inout K . Value ) -> Void ) -> some View where K: _ViewTraitKey {
129- preconditionFailure ( " TODO " )
216+ modifier ( TraitTransformerModifier < K > ( transform : transform ) )
130217 }
131218}
132219
0 commit comments