IMO SwiftUI feels limited b.c. it breaks itself away from the UIKit world: React succeeded because it is the DOM with all of raw HTML & CSS, a thin abstraction with official escape hatches. Mixing imperative and declarative code is natural and more abstractions can be built.
Instead, SwiftUI adopted a whole new set of primitives that doesn’t mix. Accessing the underlying UIView is discouraged, and wrapping up UIKit in SwiftUI feels like a legacy feature. IMO SwiftUI should have been a thin wrapper on UIKit.
There are official escape hatches in SwiftUI to let you leverage UIKit. As someone actively working on a slow migration from UIKit to SwiftUI (where possible), it doesn't feel discouraging to wrap a UIKit view to use it in SwiftUI if necessary.
That’s more of a compatibility solution than an escape hatch. An official SwiftUI escape hatch should have access to the underlying imperative object, call methods on it, etc… Unfortunately the underlying ‘things’ in SwiftUI is implementation detail, inspecting the view hierarchy and finding the UIViews that implement a SwiftUI view is a hack.
As I understand it, what you’re asking for is fundamentally incompatible with the paradigm itself (at least in a clean way).
The whole programming experience of declarative UIs is predicated on the fact that you’re manipulating lightweight structs (really just state representations) that are rendered into heavyweight views by the system only where necessary (determined by diffing the state changes).
React’s refs are an attempted answer to this very problem, and they get nasty fast.
Yup, and my understanding of the problem is that if you expose the heavy weight views to the state layer (structs) and allow direct manipulation, render calls lose incompetency, the structs are no longer the source of state truth and the whole abstraction gets terribly leaky.
Edit: once again I think it’s important to look at the limitations and advantages of prior work in this area and I believe React refs to be a good case study in that.
Instead, SwiftUI adopted a whole new set of primitives that doesn’t mix. Accessing the underlying UIView is discouraged, and wrapping up UIKit in SwiftUI feels like a legacy feature. IMO SwiftUI should have been a thin wrapper on UIKit.