11import SwiftUI
22
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+ }
528
629/// ⚓️
730struct IntrospectionAnchorView : PlatformViewControllerRepresentable {
@@ -14,9 +37,9 @@ struct IntrospectionAnchorView: PlatformViewControllerRepresentable {
1437 @Binding
1538 private var observed : Void // workaround for state changes not triggering view updates
1639
17- let id : IntrospectionAnchorID
40+ let id : IntrospectionViewID
1841
19- init ( id: IntrospectionAnchorID ) {
42+ init ( id: IntrospectionViewID ) {
2043 self . _observed = . constant( ( ) )
2144 self . id = id
2245 }
@@ -31,36 +54,19 @@ struct IntrospectionAnchorView: PlatformViewControllerRepresentable {
3154}
3255
3356final class IntrospectionAnchorPlatformViewController : PlatformViewController {
34- let id : IntrospectionAnchorID
35-
36- init ( id: IntrospectionAnchorID ) {
37- self . id = id
57+ init ( id: IntrospectionViewID ) {
3858 super. init ( nibName: nil , bundle: nil )
59+ IntrospectionStore . shared [ id, default: . init( ) ] . anchor = self
3960 }
4061
4162 @available ( * , unavailable)
4263 required init ? ( coder: NSCoder ) {
4364 fatalError ( " init(coder:) has not been implemented " )
4465 }
4566
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)
6068 override func loadView( ) {
61- let view = TaggableView ( )
62- view. tag = id. hashValue
63- self . view = view
69+ view = NSView ( )
6470 }
6571 #endif
6672}
@@ -78,14 +84,17 @@ struct IntrospectionView<Target: PlatformEntity>: PlatformViewControllerRepresen
7884
7985 @Binding
8086 private var observed : Void // workaround for state changes not triggering view updates
87+ private let id : IntrospectionViewID
8188 private let selector : ( IntrospectionPlatformViewController ) -> Target ?
8289 private let customize : ( Target ) -> Void
8390
8491 init (
92+ id: IntrospectionViewID ,
8593 selector: @escaping ( IntrospectionPlatformViewController ) -> Target ? ,
8694 customize: @escaping ( Target ) -> Void
8795 ) {
8896 self . _observed = . constant( ( ) )
97+ self . id = id
8998 self . selector = selector
9099 self . customize = customize
91100 }
@@ -95,7 +104,7 @@ struct IntrospectionView<Target: PlatformEntity>: PlatformViewControllerRepresen
95104 }
96105
97106 func makePlatformViewController( context: Context ) -> IntrospectionPlatformViewController {
98- let controller = IntrospectionPlatformViewController { controller in
107+ let controller = IntrospectionPlatformViewController ( id : id ) { controller in
99108 guard let target = selector ( controller) else {
100109 return
101110 }
@@ -128,16 +137,22 @@ struct IntrospectionView<Target: PlatformEntity>: PlatformViewControllerRepresen
128137}
129138
130139final class IntrospectionPlatformViewController : PlatformViewController {
140+ let id : IntrospectionViewID
131141 var handler : ( ( ) -> Void ) ? = nil
132142
133- fileprivate init ( handler: ( ( IntrospectionPlatformViewController ) -> Void ) ? ) {
143+ fileprivate init (
144+ id: IntrospectionViewID ,
145+ handler: ( ( IntrospectionPlatformViewController ) -> Void ) ?
146+ ) {
147+ self . id = id
134148 super. init ( nibName: nil , bundle: nil )
135149 self . handler = { [ weak self] in
136150 guard let self = self else {
137151 return
138152 }
139153 handler ? ( self )
140154 }
155+ IntrospectionStore . shared [ id, default: . init( ) ] . controller = self
141156 }
142157
143158 @available ( * , unavailable)
@@ -146,13 +161,14 @@ final class IntrospectionPlatformViewController: PlatformViewController {
146161 }
147162
148163 #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
151167 handler ? ( )
152168 }
153169
154- override func viewDidLoad ( ) {
155- super. viewDidLoad ( )
170+ override func didMove ( toParent parent : UIViewController ? ) {
171+ super. didMove ( toParent : parent )
156172 handler ? ( )
157173 }
158174
@@ -168,6 +184,7 @@ final class IntrospectionPlatformViewController: PlatformViewController {
168184 #elseif canImport(AppKit)
169185 override func loadView( ) {
170186 view = NSView ( )
187+ view. introspectionController = self
171188 }
172189
173190 override func viewDidLoad( ) {
@@ -181,3 +198,18 @@ final class IntrospectionPlatformViewController: PlatformViewController {
181198 }
182199 #endif
183200}
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