我希望能够将对 UIViewRespresentable
(或者可能是 Coordinator
)方法的引用传递给父 View
。我能想到的唯一方法是在父级 View
结构上创建一个字段,其中包含一个类,然后我将该类传递给子级,该子级充当此行为的委托(delegate)。但这似乎很冗长。
这里的用例是能够从标准的 SwiftUI Button
调用一个方法,该方法将缩放 MKMapView
中的当前位置,MKMapView
隐藏在 UIViewRepresentable
在树的其他地方。我不希望当前位置成为 Binding
,因为我希望此操作是一次性的,而不是经常反射(reflect)在 UI 中。
TL;DR 至少对于 UIViewRepresentable
而言,是否有一种标准方法可以让父级在 SwiftUI 中获取对子级的引用? (我知道这在大多数情况下可能是不可取的,并且在很大程度上不符合 SwiftUI 模式)。
最佳答案
我自己也在努力解决这个问题,下面是使用 Combine
和 PassthroughSubject
的方法:
struct OuterView: View {
private var didChange = PassthroughSubject<String, Never>()
var body: some View {
VStack {
// send the PassthroughSubject over
Wrapper(didChange: didChange)
Button(action: {
self.didChange.send("customString")
})
}
}
}
// This is representable struct that acts as the bridge between UIKit <> SwiftUI
struct Wrapper: UIViewRepresentable {
var didChange: PassthroughSubject<String, Never>
@State var cancellable: AnyCancellable? = nil
func makeUIView(context: Context) → SomeView {
let someView = SomeView()
// ... perform some initializations here
// doing it in `main` thread is required to avoid the state being modified during
// a view update
DispatchQueue.main.async {
// very important to capture it as a variable, otherwise it'll be short lived.
self.cancellable = didChange.sink { (value) in
print("Received: \(value)")
// here you can do a switch case to know which method to call
// on your UIKit class, example:
if (value == "customString") {
// call your function!
someView.customFunction()
}
}
}
return someView
}
}
// This is your usual UIKit View
class SomeView: UIView {
func customFunction() {
// ...
}
}
关于swift - 如何从 SwiftUI 中的 UIViewRepresentable 外部调用 UIView 上的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58039286/