Add a preference key to NSViewPepresentable/UIViewRepresentable in SwiftUI
1st
June 2024
It is possible to achieve by embedding a private UIViewRepresentable in a View and using State/Binding to enable “upward” communication.
Here I have modified Asperi’s answer to show the preference key being set via a Binding.
As a possible aside, I’ve found it good practice to almost always embed my UIViewRepresentable in a View to avoid UIKit “leaking” into my SwiftUI code.
struct DemoView: View { @State private var diag = CGFloat.zero var body: some View { VStack { Text("Diagnostic >> \(diag)") .background(MyUIRep()) } .onPreferenceChange(MyPrefKey.self) { value in self.diag = value } } } struct MyUIRep: View { @State private var myPrefKeyValue = CGFloat.zero var body: some View { _MyUIRep(myPrefKeyValue: $myPrefKeyValue) .preference(key: MyPrefKey.self, value: myPrefKeyValue) } private struct _MyUIRep: UIViewRepresentable { @Binding var myPrefKeyValue: CGFloat func makeUIView(context: Context) -> UIView { return UIView() } func updateUIView(_ uiView: UIView, context: Context) { DispatchQueue.main.async { myPrefKeyValue = 13.31 } } } } struct MyPrefKey : PreferenceKey { static var defaultValue: CGFloat = .zero static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { value += nextValue() } }