1
1
//
2
- // AlignmentID .swift
3
- // OpenSwiftUI
2
+ // AlignmentGuide .swift
3
+ // OpenSwiftUICore
4
4
//
5
- // Audited for iOS 15.5
6
5
// Status: Complete
6
+ // ID: E20796D15DD3D417699102559E024115 (SwiftUI)
7
+ // ID: 1135C055CD2C2B1265C25B13E3E74C01 (SwiftUICore)
7
8
8
9
public import Foundation
9
10
11
+ // MARK: - AlignmentID [6.4.41]
12
+
10
13
/// A type that you use to create custom alignment guides.
11
14
///
12
15
/// Every built-in alignment guide that ``VerticalAlignment`` or
@@ -70,7 +73,7 @@ public import Foundation
70
73
/// of the top-most rectangle in each stack are aligned with each
71
74
/// other.](AlignmentId-1-iOS)
72
75
///
73
- /// You can also use the ``View/alignmentGuide(_:computeValue:)-6y3u2 `` view
76
+ /// You can also use the ``View/alignmentGuide(_:computeValue:)`` view
74
77
/// modifier to alter the behavior of your custom guide for a view, as you
75
78
/// might alter a built-in guide. For example, you can change
76
79
/// one of the stacks of stripes from the previous example to align its
@@ -119,7 +122,7 @@ public protocol AlignmentID {
119
122
///
120
123
/// You can override the default value that this method returns for a
121
124
/// particular guide by adding the
122
- /// ``View/alignmentGuide(_:computeValue:)-9mdoh `` view modifier to a
125
+ /// ``View/alignmentGuide(_:computeValue:)`` view modifier to a
123
126
/// particular view.
124
127
///
125
128
/// - Parameter context: The context of the view that you apply
@@ -132,7 +135,9 @@ public protocol AlignmentID {
132
135
/// - Returns: The offset of the guide from the origin in the
133
136
/// view's coordinate space.
134
137
static func defaultValue( in context: ViewDimensions ) -> CGFloat
135
-
138
+
139
+ /// Updates `parentValue` with the `n`th explicit child guide value, as
140
+ /// projected into the parent's coordinate space.
136
141
static func _combineExplicit( childValue: CGFloat , _ n: Int , into parentValue: inout CGFloat ? )
137
142
}
138
143
@@ -151,10 +156,61 @@ extension AlignmentID {
151
156
let n = CGFloat ( n)
152
157
parentValue = ( value * n + childValue) / ( n + 1.0 )
153
158
}
159
+
160
+ package static func combineExplicit< S> ( _ values: S ) -> CGFloat ? where S: Sequence , S. Element == CGFloat ? {
161
+ var result : CGFloat ? = nil
162
+ var n = 0
163
+ for childValue in values {
164
+ guard let childValue else {
165
+ continue
166
+ }
167
+ _combineExplicit ( childValue: childValue, n, into: & result)
168
+ n += 1
169
+ }
170
+ return result
171
+ }
154
172
}
155
173
156
174
protocol FrameAlignment : AlignmentID { }
157
175
158
176
extension FrameAlignment {
159
177
static func _combineExplicit( childValue _: CGFloat , _: Int , into _: inout CGFloat ? ) { }
160
178
}
179
+
180
+
181
+ // MARK: - AlignmentKey [6.4.41]
182
+
183
+ @usableFromInline
184
+ @frozen
185
+ package struct AlignmentKey : Hashable , Comparable {
186
+ private let bits : UInt
187
+
188
+ @usableFromInline
189
+ package static func < ( lhs: AlignmentKey , rhs: AlignmentKey ) -> Bool {
190
+ lhs. bits < rhs. bits
191
+ }
192
+
193
+ @AtomicBox
194
+ private static var typeCache = TypeCache ( typeIDs: [ : ] , types: [ ] )
195
+
196
+ struct TypeCache {
197
+ var typeIDs : [ ObjectIdentifier : UInt ]
198
+ var types : [ AlignmentID . Type ]
199
+ }
200
+
201
+ init ( id: AlignmentID . Type , axis _: Axis ) {
202
+ let index : UInt
203
+ if let value = AlignmentKey . typeCache. typeIDs [ ObjectIdentifier ( id) ] {
204
+ index = value
205
+ } else {
206
+ index = UInt ( AlignmentKey . typeCache. types. count)
207
+ AlignmentKey . typeCache. types. append ( id)
208
+ AlignmentKey . typeCache. typeIDs [ ObjectIdentifier ( id) ] = index
209
+ }
210
+ bits = index * 2 + 3
211
+ }
212
+
213
+ var id : AlignmentID . Type {
214
+ AlignmentKey . typeCache. types [ Int ( bits / 2 - 1 ) ]
215
+ }
216
+ }
0 commit comments