1
1
import SwiftUI
2
2
3
- @_spi ( Internals)
4
- public typealias IntrospectionAnchorID = UUID
3
+ typealias IntrospectionViewID = UUID
4
+
5
+ fileprivate enum IntrospectionStore {
6
+ static var shared : [ IntrospectionViewID : Pair ] = [ : ]
7
+
8
+ struct Pair {
9
+ weak var controller : IntrospectionPlatformViewController ?
10
+ weak var anchor : IntrospectionAnchorPlatformViewController ?
11
+ }
12
+ }
13
+
14
+ extension PlatformEntity {
15
+ var introspectionAnchorEntity : Base ? {
16
+ if let introspectionController = self as? IntrospectionPlatformViewController {
17
+ return IntrospectionStore . shared [ introspectionController. id] ? . anchor~
18
+ }
19
+ if
20
+ let view = self as? PlatformView ,
21
+ let introspectionController = view. introspectionController
22
+ {
23
+ return IntrospectionStore . shared [ introspectionController. id] ? . anchor? . view~
24
+ }
25
+ return nil
26
+ }
27
+ }
5
28
6
29
/// ⚓️
7
30
struct IntrospectionAnchorView : PlatformViewControllerRepresentable {
@@ -14,9 +37,9 @@ struct IntrospectionAnchorView: PlatformViewControllerRepresentable {
14
37
@Binding
15
38
private var observed : Void // workaround for state changes not triggering view updates
16
39
17
- let id : IntrospectionAnchorID
40
+ let id : IntrospectionViewID
18
41
19
- init ( id: IntrospectionAnchorID ) {
42
+ init ( id: IntrospectionViewID ) {
20
43
self . _observed = . constant( ( ) )
21
44
self . id = id
22
45
}
@@ -31,36 +54,19 @@ struct IntrospectionAnchorView: PlatformViewControllerRepresentable {
31
54
}
32
55
33
56
final class IntrospectionAnchorPlatformViewController : PlatformViewController {
34
- let id : IntrospectionAnchorID
35
-
36
- init ( id: IntrospectionAnchorID ) {
37
- self . id = id
57
+ init ( id: IntrospectionViewID ) {
38
58
super. init ( nibName: nil , bundle: nil )
59
+ IntrospectionStore . shared [ id, default: . init( ) ] . anchor = self
39
60
}
40
61
41
62
@available ( * , unavailable)
42
63
required init ? ( coder: NSCoder ) {
43
64
fatalError ( " init(coder:) has not been implemented " )
44
65
}
45
66
46
- #if canImport(UIKit)
47
- override func viewDidLoad( ) {
48
- super. viewDidLoad ( )
49
- view. tag = id. hashValue
50
- }
51
- #elseif canImport(AppKit)
52
- final class TaggableView : NSView {
53
- private var _tag : Int ?
54
- override var tag : Int {
55
- get { _tag ?? super. tag }
56
- set { _tag = newValue }
57
- }
58
- }
59
-
67
+ #if canImport(AppKit) && !targetEnvironment(macCatalyst)
60
68
override func loadView( ) {
61
- let view = TaggableView ( )
62
- view. tag = id. hashValue
63
- self . view = view
69
+ view = NSView ( )
64
70
}
65
71
#endif
66
72
}
@@ -78,14 +84,17 @@ struct IntrospectionView<Target: PlatformEntity>: PlatformViewControllerRepresen
78
84
79
85
@Binding
80
86
private var observed : Void // workaround for state changes not triggering view updates
87
+ private let id : IntrospectionViewID
81
88
private let selector : ( IntrospectionPlatformViewController ) -> Target ?
82
89
private let customize : ( Target ) -> Void
83
90
84
91
init (
92
+ id: IntrospectionViewID ,
85
93
selector: @escaping ( IntrospectionPlatformViewController ) -> Target ? ,
86
94
customize: @escaping ( Target ) -> Void
87
95
) {
88
96
self . _observed = . constant( ( ) )
97
+ self . id = id
89
98
self . selector = selector
90
99
self . customize = customize
91
100
}
@@ -95,7 +104,7 @@ struct IntrospectionView<Target: PlatformEntity>: PlatformViewControllerRepresen
95
104
}
96
105
97
106
func makePlatformViewController( context: Context ) -> IntrospectionPlatformViewController {
98
- let controller = IntrospectionPlatformViewController { controller in
107
+ let controller = IntrospectionPlatformViewController ( id : id ) { controller in
99
108
guard let target = selector ( controller) else {
100
109
return
101
110
}
@@ -128,16 +137,22 @@ struct IntrospectionView<Target: PlatformEntity>: PlatformViewControllerRepresen
128
137
}
129
138
130
139
final class IntrospectionPlatformViewController : PlatformViewController {
140
+ let id : IntrospectionViewID
131
141
var handler : ( ( ) -> Void ) ? = nil
132
142
133
- fileprivate init ( handler: ( ( IntrospectionPlatformViewController ) -> Void ) ? ) {
143
+ fileprivate init (
144
+ id: IntrospectionViewID ,
145
+ handler: ( ( IntrospectionPlatformViewController ) -> Void ) ?
146
+ ) {
147
+ self . id = id
134
148
super. init ( nibName: nil , bundle: nil )
135
149
self . handler = { [ weak self] in
136
150
guard let self = self else {
137
151
return
138
152
}
139
153
handler ? ( self )
140
154
}
155
+ IntrospectionStore . shared [ id, default: . init( ) ] . controller = self
141
156
}
142
157
143
158
@available ( * , unavailable)
@@ -146,13 +161,14 @@ final class IntrospectionPlatformViewController: PlatformViewController {
146
161
}
147
162
148
163
#if canImport(UIKit)
149
- override func didMove( toParent parent: UIViewController ? ) {
150
- super. didMove ( toParent: parent)
164
+ override func viewDidLoad( ) {
165
+ super. viewDidLoad ( )
166
+ view. introspectionController = self
151
167
handler ? ( )
152
168
}
153
169
154
- override func viewDidLoad ( ) {
155
- super. viewDidLoad ( )
170
+ override func didMove ( toParent parent : UIViewController ? ) {
171
+ super. didMove ( toParent : parent )
156
172
handler ? ( )
157
173
}
158
174
@@ -168,6 +184,7 @@ final class IntrospectionPlatformViewController: PlatformViewController {
168
184
#elseif canImport(AppKit)
169
185
override func loadView( ) {
170
186
view = NSView ( )
187
+ view. introspectionController = self
171
188
}
172
189
173
190
override func viewDidLoad( ) {
@@ -181,3 +198,18 @@ final class IntrospectionPlatformViewController: PlatformViewController {
181
198
}
182
199
#endif
183
200
}
201
+
202
+ import ObjectiveC
203
+
204
+ extension PlatformView {
205
+ fileprivate var introspectionController : IntrospectionPlatformViewController ? {
206
+ get {
207
+ let key = unsafeBitCast ( Selector ( #function) , to: UnsafeRawPointer . self)
208
+ return objc_getAssociatedObject ( self , key) as? IntrospectionPlatformViewController
209
+ }
210
+ set {
211
+ let key = unsafeBitCast ( Selector ( #function) , to: UnsafeRawPointer . self)
212
+ objc_setAssociatedObject ( self , key, newValue, . OBJC_ASSOCIATION_ASSIGN)
213
+ }
214
+ }
215
+ }
0 commit comments