@@ -5,7 +5,21 @@ import SwiftUI
5
5
6
6
extension View {
7
7
func debugLayout( _ label: String ) -> some View {
8
- DebugLayout ( label: label) { self }
8
+ DebugLayout ( label: label) {
9
+ self
10
+ }
11
+ . modifier ( DebugLayoutWrapper ( label: label) )
12
+ }
13
+ }
14
+
15
+ struct DebugLayoutWrapper : ViewModifier {
16
+ var label : String
17
+ @Environment ( \. debugLayoutSelection) private var selection : String ?
18
+
19
+ func body( content: Content ) -> some View {
20
+ let isSelected = label == selection
21
+ content
22
+ . border ( isSelected ? Color . blue : . clear, width: 2 )
9
23
}
10
24
}
11
25
@@ -90,36 +104,68 @@ func log(_ label: String, action: String, value: String) {
90
104
}
91
105
}
92
106
107
+ struct DebugLayoutSelection : EnvironmentKey {
108
+ static var defaultValue : String ? { nil }
109
+ }
110
+
111
+ extension EnvironmentValues {
112
+ var debugLayoutSelection : String ? {
113
+ get { self [ DebugLayoutSelection . self] }
114
+ set { self [ DebugLayoutSelection . self] = newValue }
115
+ }
116
+ }
117
+
118
+ struct Selection < Value: Equatable > : PreferenceKey {
119
+ static var defaultValue : Value ? { nil }
120
+
121
+ static func reduce( value: inout Value ? , nextValue: ( ) -> Value ? ) {
122
+ value = value ?? nextValue ( )
123
+ }
124
+ }
125
+
93
126
struct ConsoleView : View {
94
127
@ObservedObject var console = Console . shared
128
+ @State private var selection : String ? = nil
95
129
96
130
var body : some View {
97
131
ScrollView ( . vertical) {
98
132
VStack ( alignment: . leading, spacing: 16 ) {
99
133
Text ( " Layout Log " )
100
134
. font ( . headline)
135
+ . padding ( . top, 16 )
136
+ . padding ( . horizontal, 8 )
101
137
102
- Grid ( alignment: . leadingFirstTextBaseline, horizontalSpacing: 8 , verticalSpacing: 8 ) {
138
+ Grid ( alignment: . leadingFirstTextBaseline, horizontalSpacing: 0 , verticalSpacing: 0 ) {
103
139
ForEach ( console. log) { item in
140
+ let isSelected = selection == item. label
104
141
GridRow {
105
142
Text ( item. label)
106
143
. frame ( maxWidth: . infinity, alignment: . leading)
144
+ . padding ( . horizontal, 8 )
107
145
108
146
Text ( item. action)
109
147
. font ( . headline)
110
148
111
149
Text ( item. value)
112
150
. monospacedDigit ( )
113
151
. gridColumnAlignment ( . trailing)
152
+ . padding ( . horizontal, 8 )
153
+ }
154
+ . padding ( . vertical, 8 )
155
+ . foregroundColor ( isSelected ? . white : nil )
156
+ . background ( isSelected ? Color . accentColor : . clear)
157
+ . contentShape ( Rectangle ( ) )
158
+ . onTapGesture {
159
+ selection = isSelected ? nil : item. label
114
160
}
115
161
116
162
Divider ( )
117
163
. gridCellUnsizedAxes ( . horizontal)
118
164
}
119
165
}
120
166
}
121
- . padding ( )
122
167
}
123
168
. background ( Color ( uiColor: . secondarySystemBackground) )
169
+ . preference ( key: Selection . self, value: selection)
124
170
}
125
171
}
0 commit comments