4

I want to load a webView inside the new SwiftUI framework. How can I do that?

struct SubmissionFlowFrame: View {

    var body: some View {
        // I want to insert the iframe here
    }
}
mikeTeixeira88
  • 163
  • 2
  • 8
  • Unless it's a native SwiftUI `View` (which I don't believe it is), you'll need to (1) get it working in `UIKit` as you want (either as a view or view controller) and (2) make it "relatable" (as in `UIViewRelatable` or `UIViewControllerRelatable`. There are a few questions here with accepted answers along with a few pretty good examples out there. Good luck! –  Jul 16 '19 at 11:28

5 Answers5

4

You can use any UIView by conforming to UIViewRepresentable and implement needed methods like this:

struct WebView: UIViewRepresentable {

    func makeUIView(context: Context) -> WKWebView {
        WKWebView(frame: .zero)
    }

    func updateUIView(_ view: WKWebView, context: UIViewRepresentableContext<WebView>) {

        let request = URLRequest(url: URL(string: "https://google.com")!)

        view.load(request)
    }
}

and then use it like a normal swiftUI View like this:

struct ContentView : View {

    var body: some View {
        WebView()
    }
}

And don't forget to import UIKit dependencies like for this case:

import WebKit
1
import SwiftUI
import WebKit

struct WebView: UIViewRepresentable {

    func makeUIView(context: UIViewRepresentableContext<WebView>) -> WebView.UIViewType {
        WKWebView(frame: .zero)
    }

    func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<WebView>) {
        let request = URLRequest(url: URL(string: "https://apple.com")!)
        uiView.load(request)
    }

}

struct ContentView: View {

    var body: some View {
        WebView()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Sanjay Mishra
  • 672
  • 7
  • 17
0

well, currently no direct methods are available for that.

but you can use UIViewRepresentable for that and wrap view with it.

like this:

struct ContentView : UIViewRepresentable {

    func makeUIView(context: Context) -> WKWebView  {
        let webView = WKWebView()
        let request = URLRequest(url: URL(string: "https://www.apple.com")!)
        webView.load(request)
        return webView
    }

    func updateUIView(_ uiView: WKWebView, context: Context) { }
}

#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

don't forget to import WebKit.

Marcela
  • 11
  • 5
Ketan Odedra
  • 1,215
  • 10
  • 35
0

You can wrap the webView inside SwiftUI using UIViewRepresentable.

import SwiftUI
import WebKit

struct ContentView: View {
  var body: some View {
    WebView()
  }
}

struct WebView: UIViewRepresentable {
  func makeUIView(context: Context) -> WKWebView {
    return WKWebView()
  }
  func updateUIView(_ webView: WKWebView, context: Context) {
        let request = URLRequest(url: URL(string: "https://www.apple.com")!)
        webView.load(request)
  }
}
Sreeraj VR
  • 1,524
  • 19
  • 35
0

Use WebView to load url request like:

WebView {
    $0.load(URLRequest(url: .init(string: "https://google.com")!))
}

With this simple struct

import WebKit
struct WebView: ViewRepresentableHelper {
    var configuration = { (view: WKWebView) in } //  This has a gift for you
}

Bouns!

You can replace WKWebView with almost ANY other UIKit or AppKit component to make it available right in the SwiftUI code! For example:

struct IndicatorView: ViewRepresentableHelper {
    var configuration = { (view: UIActivityIndicatorView) in }
}

usage:

IndicatorView {
    $0.startAnimating()
}

Works on both iOS and macOS

Dont forget to implement this powerful extesnion:

#if os(macOS)
public typealias ViewRepresentable = NSViewRepresentable
public typealias NativeView = NSView
#elseif os(iOS)
public typealias ViewRepresentable = UIViewRepresentable
public typealias NativeView = UIView
#endif

public protocol ViewRepresentableHelper: ViewRepresentable {
    associatedtype ViewType: NativeView
    var configuration: (ViewType) -> () { get set }
    func new() -> ViewType
}

public extension ViewRepresentableHelper {
    func new() -> ViewType { ViewType() }
}

public extension ViewRepresentableHelper {
    func makeView(_ context: Context) -> ViewType {
        let view = new()
        view.setContentHuggingPriority(.defaultHigh, for: .vertical)
        view.setContentHuggingPriority(.defaultHigh, for: .horizontal)
        return view
    }
    func updateView(_ view: ViewType, _ context: Context) { configuration(view) }

    func makeUIView(context: Context) -> ViewType { makeView(context) }
    func makeNSView(context: Context) -> ViewType { makeView(context) }
    func updateUIView(_ uiView: ViewType, context: Context) { updateView(uiView, context) }
    func updateNSView(_ nsView: ViewType, context: Context) { updateView(nsView, context) }
}
Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278