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

时间:2020-11-08 10:57:33

标签: ios swift webview swiftui swiftui-list

我正在建立一个包含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")
    }
}

WebView:

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 个答案:

答案 0 :(得分:0)

您需要在单个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.stackoverflow.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) {}
}