Since there are some components not available in SwiftUI, we can adapt some from UIKit. This is necessary when, for example, we want to implement a delegate
.
Let's look at the example of a WKWebView
that we want to load in our SwiftUI code, and we also want to implement WKNavigationDelegate
, which will notify us when the web content has finished loading.
The first step is to create a struct
(which we've called "WebView") that implements the UIViewRepresentable
protocol. This struct
has three parts:
- The
URLRequest
, which we will define from our view later. - The
makeUIView(context:)
function, where we must return the component we want to load, in this case, aWKWebView
. - The
updateUIView(_:, context:)
function, which will be triggered when the system detects an important UI update, for example, when our screen is loaded. We will use it to load theURLRequest
in our WebView.
import WebKit
struct WebView: UIViewRepresentable {
let request: URLRequest
func makeUIView(context: Context) -> WKWebView {
return WKWebView()
}
func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.load(request)
}
}
Finally, we'll use our new component like any other, injecting the URL into its initializer.
struct ContentView: View {
var body: some View {
if let url = URL(string: "https://educaswift.com") {
VStack {
Text("This is my embedded web view")
.font(.headline)
WebView(request: URLRequest(url: url))
}
.padding()
}
}
}
Coordinator
To be able to implement a delegate
for our WebView
, we need to use a Coordinator
.
struct WebView: UIViewRepresentable {
let request: URLRequest
// 1
class Coordinator: NSObject, WKNavigationDelegate {
let parent: WebView
init(parent: WebView) {
self.parent = parent
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("The Web View has finished loading!")
}
}
// 2
func makeCoordinator() -> Coordinator {
return Coordinator(parent: self)
}
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
// 3
webView.navigationDelegate = context.coordinator
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.load(request)
}
}
Let's review the code we've added:
- 1. We create an object called
Coordinator
, which will be responsible for implementing thedelegate
. - 2. We implement
makeCoordinator()
, where we initialize an instance ofCoordinator
. - 3. When creating our
WKWebView
, we set its delegate to theCoordinator
we just created.
Be the first to comment