3
3
// OpenSwiftUICore
4
4
//
5
5
// Audited for 6.5.4
6
- // Status: WIP
6
+ // Status: Complete
7
7
// ID: 47C1BD8C61550BB60F4F3D12F752D53D (SwiftUICore)
8
8
9
- private struct DefaultPaddingKey : EnvironmentKey {
10
- static let defaultValue : EdgeInsets = . init( _all: 16.0 )
11
- }
9
+ import Foundation
10
+ import OpenGraphShims
12
11
13
12
@available ( OpenSwiftUI_v3_0, * )
14
13
extension EnvironmentValues {
@@ -19,17 +18,114 @@ extension EnvironmentValues {
19
18
}
20
19
}
21
20
21
+ // MARK: - DefaultPaddingKey
22
+
23
+ private struct DefaultPaddingKey : EnvironmentKey {
24
+ static let defaultValue : EdgeInsets = . init( _all: 16.0 )
25
+ }
26
+
22
27
@available ( OpenSwiftUI_v2_0, * )
23
28
extension View {
24
29
/// For use by children in containers to disable the automatic padding that
25
30
/// those containers apply.
26
31
public func _ignoresAutomaticPadding( _ ignoresPadding: Bool ) -> some View {
27
- _openSwiftUIUnimplementedFailure ( )
32
+ modifier ( IgnoresAutomaticPaddingLayout ( ignoresPadding : ignoresPadding ) )
28
33
}
29
34
30
35
/// Applies explicit padding to a view that allows being disabled by that
31
36
/// view using `_ignoresAutomaticPadding`.
32
37
public func _automaticPadding( _ edgeInsets: EdgeInsets ? = nil ) -> some View {
33
- _openSwiftUIUnimplementedFailure ( )
38
+ modifier ( AutomaticPaddingViewModifier ( padding: edgeInsets) )
39
+ }
40
+ }
41
+
42
+ // MARK: - AutomaticPaddingViewModifier
43
+
44
+ private struct AutomaticPaddingViewModifier : MultiViewModifier , PrimitiveViewModifier {
45
+ var padding : EdgeInsets ?
46
+
47
+ nonisolated static func _makeView(
48
+ modifier: _GraphValue < AutomaticPaddingViewModifier > ,
49
+ inputs: _ViewInputs ,
50
+ body: @escaping ( _Graph , _ViewInputs ) -> _ViewOutputs
51
+ ) -> _ViewOutputs {
52
+ guard inputs. requestsLayoutComputer || inputs. needsGeometry else {
53
+ return body ( _Graph ( ) , inputs)
54
+ }
55
+ let layout = Attribute ( PaddingLayout (
56
+ modifier: modifier. value,
57
+ environment: inputs. environment,
58
+ childLayoutComputer: . init( )
59
+ ) )
60
+ return PaddingLayout . Value. makeDebuggableView (
61
+ modifier: _GraphValue ( layout) ,
62
+ inputs: inputs,
63
+ body: body
64
+ )
65
+ }
66
+
67
+ struct PaddingLayout : Rule , AsyncAttribute {
68
+ @Attribute var modifier : AutomaticPaddingViewModifier
69
+ @Attribute var environment : EnvironmentValues
70
+ @OptionalAttribute var childLayoutComputer : LayoutComputer ?
71
+
72
+ typealias Value = ModifiedContent < WrappedLayout , _SafeAreaInsetsModifier >
73
+
74
+ var value : Value {
75
+ let ignoresAutomaticPadding = childLayoutComputer? . ignoresAutomaticPadding ( ) ?? false
76
+ let padding : EdgeInsets
77
+ if ignoresAutomaticPadding {
78
+ padding = . zero
79
+ } else {
80
+ padding = modifier. padding ?? environment. defaultPadding
81
+ }
82
+ return WrappedLayout ( base: . init( insets: padding) )
83
+ . concat ( _SafeAreaInsetsModifier ( insets: padding) )
84
+ }
85
+
86
+ struct WrappedLayout : UnaryLayout {
87
+ var base : _PaddingLayout
88
+
89
+ func placement(
90
+ of child: LayoutProxy ,
91
+ in context: PlacementContextType
92
+ ) -> _Placement {
93
+ base. placement ( of: child, in: context)
94
+ }
95
+
96
+ func sizeThatFits(
97
+ in proposedSize: _ProposedSize ,
98
+ context: SizeAndSpacingContext ,
99
+ child: LayoutProxy
100
+ ) -> CGSize {
101
+ base. sizeThatFits ( in: proposedSize, context: context, child: child)
102
+ }
103
+ }
104
+ }
105
+ }
106
+
107
+ // MARK: - IgnoresAutomaticPaddingLayout
108
+
109
+ private struct IgnoresAutomaticPaddingLayout : UnaryLayout {
110
+ var ignoresPadding : Bool
111
+
112
+ func placement( of child: LayoutProxy , in context: PlacementContext ) -> _Placement {
113
+ _Placement (
114
+ proposedSize: context. proposedSize,
115
+ aligning: . center,
116
+ in: context. size
117
+ )
118
+ }
119
+
120
+ func sizeThatFits( in proposedSize: _ProposedSize , context: SizeAndSpacingContext , child: LayoutProxy ) -> CGSize {
121
+ child. size ( in: proposedSize)
122
+ }
123
+
124
+ func layoutPriority( child: LayoutProxy ) -> Double {
125
+ child. layoutPriority
126
+ }
127
+
128
+ func ignoresAutomaticPadding( child: LayoutProxy ) -> Bool {
129
+ ignoresPadding
34
130
}
35
131
}
0 commit comments