在列表中加载 WebView 而无需重新加载 webView 内容 SwiftUI

Posted

技术标签:

【中文标题】在列表中加载 WebView 而无需重新加载 webView 内容 SwiftUI【英文标题】:Load WebView inside a List without reloading webView content SwiftUI 【发布时间】:2020-11-08 10:57:33 【问题描述】:

我正在构建一个包含 webView 的列表。

如果视图可见,列表会重新创建视图。

我的问题是-如果有办法不重新创建 webView 并且只加载一次。

我知道我可以使用 ScrollView 来避免娱乐,但我需要它来使用 List。

在 UIKit 中,我将 webView 加载到单元格之外,并将其添加到“cellForRow”函数的正确 indexPath 中。

如何在 SwiftUI 中做类似的事情?

这是我的代码: 列表:

import SwiftUI

struct ListView: View 
    let title: String
    
    var body: some View 
        List 
            LoremText()
            LoremText()
            LoremText()
            LoremText()
            LoremText()
            LoremText()
            LoremText()
            LoremText()
            LoremText()
            WebView(url: URL.init(string: "https://www.google.com")!).frame(height: 300, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
        .navigationBarTitle(title)
    


struct ListView_Previews: PreviewProvider 
    static var previews: some View 
        ListView(title: "ListView")
    

网页视图:

import SwiftUI
import WebKit

final class WebView : UIViewRepresentable 
    let request: URLRequest
      
    init(url: URL) 
        self.request = URLRequest(url: url)
    
    
    func makeUIView(context: Context) -> WKWebView  
        let view = WKWebView()
        view.scrollView.isScrollEnabled = false
        view.load(request)
        return view
    
      
    func updateUIView(_ uiView: WKWebView, context: Context) 
        
    
    

【问题讨论】:

【参考方案1】:

您需要在单个 WKWebView 周围使用包装视图,因为 List 可以重新创建/重用其中的任何单元格,因此特定的单元格视图始终是新的。

这是可能的解决方案。使用 Xcode 12.1 / ios 14.1 测试

struct ListView: View 
    let title: String
    
    var body: some View 
        List 
            LoremText()
            LoremText()
            LoremText()
            LoremText()
            LoremText()
            LoremText()
            LoremText()
            LoremText()
            LoremText()

            SingleWebView(url: URL(string: "https://www.***.com")!).frame(height: 300)
        .navigationBarTitle(title)
    


import WebKit

struct SingleWebView : UIViewRepresentable 
    static var webView: WKWebView!
    let request: URLRequest
    
    init(url: URL) 
        self.request = URLRequest(url: url)
    
    
    func makeUIView(context: Context) -> WKWebView  
        if nil == Self.webView 
            Self.webView = WKWebView()
            Self.webView.scrollView.isScrollEnabled = false
        
        if self.request.url != Self.webView.url 
            Self.webView.load(request)
        
        return Self.webView
    
    
    func updateUIView(_ uiView: WKWebView, context: Context) 

【讨论】:

如果我需要添加 2 个 webView 到列表中,在这种情况下它只会创建一个(如果我有 2 个列表,每个列表中都有 webView。)。它会永远留在记忆中。你有包装视图的例子吗?

以上是关于在列表中加载 WebView 而无需重新加载 webView 内容 SwiftUI的主要内容,如果未能解决你的问题,请参考以下文章

停止在 webViewClient 中加载

在WebView中加载gif而不是调整到WebView

在我的 Webview 在 Android Webview App 中加载之前获取白页

webview 正在模拟器中加载,但未在设备中加载

如何在 UICollectionView 中加载更多数据而不重新加载所有数据

如何在uitableview中加载数据而不每次都重新加载