1
1
//
2
2
// ViewTrait.swift
3
- // OpenSwiftUI
3
+ // OpenSwiftUICore
4
4
//
5
5
// Audited for iOS 18.0
6
- // Status: Blocked by ViewList
6
+ // Status: Complete
7
7
// ID: 9929B476764059557433A108298EE66F (SwiftUI)
8
8
// ID: 48526BA25CDCBF890FA91D018A5421B4 (SwiftUICore)
9
9
@@ -21,11 +21,11 @@ public protocol _ViewTraitKey {
21
21
static var defaultValue : Value { get }
22
22
}
23
23
24
- // MARK: - _TraitWritingModifier [TODO]
24
+ // MARK: - _TraitWritingModifier
25
25
26
26
/// A view content adapter that associates a trait with its base content.
27
27
@frozen
28
- public struct _TraitWritingModifier < Trait> : PrimitiveViewModifier where Trait : _ViewTraitKey {
28
+ public struct _TraitWritingModifier < Trait> : PrimitiveViewModifier where Trait: _ViewTraitKey {
29
29
public let value : Trait . Value
30
30
31
31
@inlinable
@@ -38,23 +38,47 @@ public struct _TraitWritingModifier<Trait>: PrimitiveViewModifier where Trait :
38
38
inputs: _ViewInputs ,
39
39
body: @escaping ( _Graph , _ViewInputs ) -> _ViewOutputs
40
40
) -> _ViewOutputs {
41
- 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
+ }
42
50
}
51
+
43
52
nonisolated public static func _makeViewList(
44
53
modifier: _GraphValue < Self > ,
45
54
inputs: _ViewListInputs ,
46
55
body: @escaping ( _Graph , _ViewListInputs ) -> _ViewListOutputs
47
56
) -> _ViewListOutputs {
48
- preconditionFailure ( " TODO " )
49
- }
50
-
51
- nonisolated public static func _viewListCount( inputs: _ViewListCountInputs , body: ( _ViewListCountInputs ) -> Int ? ) -> Int ? {
52
- 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
+ }
53
71
}
54
72
55
- private struct AddTrait {
73
+ private struct AddTrait : Rule {
56
74
@Attribute var modifier : _TraitWritingModifier
57
75
@OptionalAttribute var traits : ViewTraitCollection ?
76
+
77
+ var value : ViewTraitCollection {
78
+ var traits = traits ?? ViewTraitCollection ( )
79
+ traits [ Trait . self] = modifier. value
80
+ return traits
81
+ }
58
82
}
59
83
}
60
84
@@ -65,16 +89,17 @@ extension View {
65
89
/// Associate a trait `value` for the given `key` for this view content.
66
90
@inlinable
67
91
nonisolated public func _trait< K> ( _ key: K . Type , _ value: K . Value ) -> some View where K: _ViewTraitKey {
68
- return modifier ( _TraitWritingModifier < K > ( value: value) )
92
+ modifier ( _TraitWritingModifier < K > ( value: value) )
69
93
}
70
94
}
71
95
72
- // MARK: - _ConditionalTraitWritingModifier [TODO]
96
+ // MARK: - _ConditionalTraitWritingModifier
73
97
74
98
/// Conditionally writes a trait.
75
99
@frozen
76
100
public struct _ConditionalTraitWritingModifier < Trait> : PrimitiveViewModifier where Trait : _ViewTraitKey {
77
101
public var value : Trait . Value
102
+
78
103
public var isEnabled : Bool
79
104
80
105
@_alwaysEmitIntoClient
@@ -88,26 +113,56 @@ public struct _ConditionalTraitWritingModifier<Trait>: PrimitiveViewModifier whe
88
113
inputs: _ViewInputs ,
89
114
body: @escaping ( _Graph , _ViewInputs ) -> _ViewOutputs
90
115
) -> _ViewOutputs {
91
- preconditionFailure ( " TODO " )
116
+ _TraitWritingModifier< Trait> . _makeView(
117
+ modifier: _GraphValue ( Attribute ( identifier: AnyAttribute . nil) ) ,
118
+ inputs: inputs,
119
+ body: body
120
+ )
92
121
}
122
+
93
123
nonisolated public static func _makeViewList(
94
124
modifier: _GraphValue < Self > ,
95
125
inputs: _ViewListInputs ,
96
126
body: @escaping ( _Graph , _ViewListInputs ) -> _ViewListOutputs
97
127
) -> _ViewListOutputs {
98
- 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
+ }
99
142
}
100
143
101
- nonisolated public static func _viewListCount( inputs: _ViewListCountInputs , body: ( _ViewListCountInputs ) -> Int ? ) -> Int ? {
102
- 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
+ }
103
155
}
104
156
}
105
157
106
158
@available ( * , unavailable)
107
159
extension _ConditionalTraitWritingModifier : Sendable { }
108
160
109
161
extension View {
162
+ /// Conditionally writes a trait.
110
163
@_alwaysEmitIntoClient
164
+ @MainActor
165
+ @preconcurrency
111
166
public func _trait< K> ( _ key: K . Type = K . self, _ value: K . Value , isEnabled: Bool ) -> some View where K: _ViewTraitKey {
112
167
modifier ( _ConditionalTraitWritingModifier < K > (
113
168
value: value,
@@ -116,15 +171,49 @@ extension View {
116
171
}
117
172
}
118
173
119
- // MARK: - TraitTransformerModifier [TODO]
174
+ // MARK: - TraitTransformerModifier
120
175
121
- struct TraitTransformerModifier {
122
-
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
+ }
123
212
}
124
213
125
214
extension View {
126
215
package func transformTrait< K> ( _ key: K . Type = K . self, transform: @escaping ( inout K . Value ) -> Void ) -> some View where K: _ViewTraitKey {
127
- preconditionFailure ( " TODO " )
216
+ modifier ( TraitTransformerModifier < K > ( transform : transform ) )
128
217
}
129
218
}
130
219
0 commit comments