I want to show a WKWebView in a SwiftUI view hierarchy, and I want to control the WKWebView using buttons implemented in SwiftUI.
I can do this by creating a SwiftUI WebView
class that implements UIViewRepresentable
and wraps WKWebView
, like so...
struct WebView: UIViewRepresentable {
func makeUIView(context: UIViewRepresentableContext<WebView>) -> WKWebView {
return WKWebView(frame: .zero)
}
func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<WebView>) {
// Update WKWebView here if necessary
}
}
...and then using it as follows...
struct BrowserView: View {
var body: some View {
VStack {
WebView()
// Footer
HStack {
Button(action: {
// When this is called, I want to somehow call .goBack()
// on the WKWebView.
}) {
Image(systemName: "chevron.left")
}
...
} // HStack
} // VStack
}
}
When the user taps the Button, I want to somehow call goBack
on the WKWebView
. How am I to do this idiomatically in SwiftUI?
Approaches I've considered that I think are either brittle or aren't idiomatic SwiftUI...
Represent the number of times that a user has clicked "Back" in a binding. Have WebView listen to that binding and move back when that increments.
Have
BrowserView
create an object called something likeMutableWebViewAPI
and pass it toWebView
on construction.WebView
listens on this object so that whenBrowserView
calls something likeMutableWebViewAPI.goBack()
,WebView
does the same.