UIViewRepresentable
Using UIKit elements on SwiftUI.
UIViewRepresentable
Using UIKit elements on SwiftUI.
0
0
Checkbox to mark video as read
Mark as read

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, a WKWebView.
  • 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 the URLRequest 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 the delegate.
  • 2. We implement makeCoordinator(), where we initialize an instance of Coordinator.
  • 3. When creating our WKWebView, we set its delegate to the Coordinator we just created.

0 Comments

Join the community to comment

Be the first to comment

Accept Cookies

We use cookies to collect and analyze information on site performance and usage, in order to provide you with better service.

Check our Privacy Policy