SwiftUI导航切换时WebView内容消失,如何保持其状态?
问题原因
当从页面1导航到页面2时,SwiftUI的导航栈会将页面1的视图从当前渲染层级中移除,导致PDFWebView对应的WKWebView实例被销毁。返回页面1时,PDFWebView会重新创建WKWebView并调用updateUIView重新加载请求,因此之前的内容会消失。另外原代码中updateUIView每次都会执行load(request),即使URL没有变化,也会触发不必要的重载。
解决方案
要保持WebView的状态,需要将WKWebView实例的生命周期与SwiftUI视图的刷新解耦,具体可通过以下方式实现:
方法一:用@StateObject保存WebView实例
修改PDFWebView,通过ObservableObject管理WKWebView实例,确保它不会随视图重建被销毁:
class WebViewStore: ObservableObject { let webView: WKWebView init(url: URL) { webView = WKWebView() let request = URLRequest(url: url) webView.load(request) } } struct PDFWebView: UIViewRepresentable { @StateObject private var webViewStore: WebViewStore init(url: URL) { _webViewStore = StateObject(wrappedValue: WebViewStore(url: url)) } func makeUIView(context: Context) -> WKWebView { webViewStore.webView } func updateUIView(_ uiView: WKWebView, context: Context) { // 移除重复加载逻辑,避免不必要的重载 } }
方法二:简化NavigationView结构
原代码中GeometryReader包裹NavigationView可能触发视图频繁刷新,可简化页面1的结构,同时优化NavigationLink的绑定方式:
struct SwiftUIView: View { @State private var navigateToScreen2 = false var body: some View { NavigationView { VStack { if let url = URL(string: "https://www.africau.edu/images/default/sample.pdf") { PDFWebView(url: url) } else { Text("无效的URL") } Spacer() Button("Go to 2") { navigateToScreen2 = true } .foregroundColor(.white) .padding() .background(Color.blue) .cornerRadius(10) // 用空视图承载NavigationLink,避免按钮包装带来的布局问题 NavigationLink(destination: Screen2View(), isActive: $navigateToScreen2) { EmptyView() } } .padding() .navigationBarTitle("Screen 1") .background(Color.white) } } }
内容的提问来源于stack exchange,提问作者Daniel Frost
相关产品推荐
相关产品推荐

