工作表和警报不断刷新我的 WKWebView SwiftUI 页面

Jam*_*Lee 0 swift wkwebview swiftui

我目前正在使用 WKWebView,并在 wkwebview 中添加了一个工作表和一个警报。但是,每次我关闭工作表或关闭警报时,我的 WkWebView 都会继续导航(加载)回我指定的原始域(在本例中为 google.com)。我想知道如何解决这个问题。

网页视图

import SwiftUI
import WebKit

struct WebView : UIViewRepresentable {
    
    let request: URLRequest
    
    func makeUIView(context: Context) -> WKWebView  {
        return WKWebView()
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.load(request)
    }
    
}
Run Code Online (Sandbox Code Playgroud)

主视图

struct MainView: View {
   var webView: WebView = WebView(request: URLRequest(url: URL(string: "https://www.google.com")!))

 var body: some View {
  VStack(){
   AlertView()
   webView
   SheetScreenView(webView: $webView)
  }
 }
Run Code Online (Sandbox Code Playgroud)

警报视图()

...
  Button(action: {
  }, label: {}..alert(isPresented: $isBookmarked) {
                Alert(title: Text(" \(webView.getURL())"), dismissButton: .default(Text("Ok")))
            }
...
Run Code Online (Sandbox Code Playgroud)

工作表屏幕视图

....
@State private var showingSheet = false

    var body: some View {
        Button("Show Sheet") {
            showingSheet.toggle()
        }
        .sheet(isPresented: $showingSheet) {
            SheetView()
        }
    }
...
Run Code Online (Sandbox Code Playgroud)

工作表视图

struct SheetView: View {
    @Environment(\.presentationMode) var presentationMode

    var body: some View {
        Button("Press to dismiss") {
            presentationMode.wrappedValue.dismiss()
        }
        .font(.title)
        .padding()
        .background(Color.black)
    }
}
Run Code Online (Sandbox Code Playgroud)

jn_*_*pdx 5

即使没有工作表和警报,只需旋转设备即可重现您的问题。问题是,在updateView(这会经常被调用)中,您load调用URLRequest. 由于您将视图存储在 a 中,该视图var将在每次新渲染时重新创建MainView,因此情况会变得更加复杂,因为Views在 SwiftUI 中是瞬态的。

如果您的 URL 不打算更改,避免这种情况的最简单方法就是load调用makeUIView

struct WebView : UIViewRepresentable {
    var request: URLRequest
    
    func makeUIView(context: Context) -> WKWebView  {
        let webView = WKWebView()
        webView.load(request)
        return webView
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        
    }
}

struct ContentView: View {
    var body: some View {
      WebView(request: URLRequest(url:URL(string: "https://www.google.com")!))
    }
}

Run Code Online (Sandbox Code Playgroud)

如果您的 URL可能发生变化,您需要一种方法来将以前的状态与新的状态进行比较。这似乎是最短的(但肯定不是唯一的)方法:

struct WebView : UIViewRepresentable {
    var url: URL
    
    @State private var prevURL : URL?
    
    func makeUIView(context: Context) -> WKWebView  {
        return WKWebView()
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        if (prevURL != url) {
            let request = URLRequest(url: url)
            uiView.load(request)
            DispatchQueue.main.async { prevURL = url }
        }
    }
}

struct ContentView: View {
    var body: some View {
        WebView(url: URL(string: "https://www.google.com")!)
    }
}

Run Code Online (Sandbox Code Playgroud)