如何在 SwiftUI 中创建一个列表视图,每个列表项都是一个 WKWebView(我的实现非常慢并且有问题)
Posted
技术标签:
【中文标题】如何在 SwiftUI 中创建一个列表视图,每个列表项都是一个 WKWebView(我的实现非常慢并且有问题)【英文标题】:How to create a List view in SwiftUI with each List item being a WKWebView (my implementation is super slow and has problems) 【发布时间】:2020-08-09 05:55:36 【问题描述】:基本上,我想在 SwiftUI 中创建一个列表视图,每个列表项都是一个 WKWebView(这就像论坛中某个主题的帖子,每个帖子数据都由一些 html 字符串表示,可能包括图片和其他内容) 类似下面的东西 something like this
但是,当我完成代码时(代码附在底部),代码执行速度超级慢,同时无法滚动。如果向下滚动,某些列表项不会加载。如果你再次向上滚动,原来加载的列表项就会消失。此外,调试窗口中有很多错误消息,例如 error
2020-08-08 22:44:15.493387-0700 WKWebViewTest[2205:76254] WF: === Starting WebFilter logging for process WKWebViewTest
2020-08-08 22:44:15.493682-0700 WKWebViewTest[2205:76254] WF: _userSettingsForUser : (null)
2020-08-08 22:44:15.493865-0700 WKWebViewTest[2205:76254] WF: _WebFilterIsActive returning: NO
2020-08-08 22:44:15.622585-0700 WKWebViewTest[2205:76254] WF: _userSettingsForUser : (null)
2020-08-08 22:44:15.622787-0700 WKWebViewTest[2205:76254] WF: _WebFilterIsActive returning: NO
我想知道如何在 SwiftUI 中很好地和快速地实现这个视图。
import SwiftUI
import WebKit
struct ContentView: View
init()
UITableView.appearance().separatorStyle = .none
UITableViewCell.appearance().selectionStyle = .none
UITableViewCell.appearance().backgroundColor = UIColor.clear
UITableView.appearance().backgroundColor = UIColor.clear
let htmlText = "<p>This is the paragraph</p>"
var body: some View
List
ForEach(0...20, id: \.self) _ in
VStack
PostWebView(text: self.htmlText)
.frame(height: 50)
Divider()
.listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0))
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
struct PostWebView : UIViewRepresentable
let text: String
init(text: String)
self.text = text
class Coordinator: NSObject, WKNavigationDelegate
var parent: PostWebView
init(_ parent: PostWebView)
self.parent = parent
func makeCoordinator() -> Coordinator
Coordinator(self)
func makeUIView(context: Context) -> WKWebView
let webview = WKWebView()
webview.scrollView.bounces = false
webview.scrollView.isScrollEnabled = false
webview.navigationDelegate = context.coordinator
let htmlStart = "<HTML><HEAD><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, shrink-to-fit=no, maximum-scale=1.0, user-scalable=no\"></HEAD><BODY>"
let htmlEnd = "</BODY></HTML>"
let postHtml = text
let htmlString = "\(htmlStart)\(postHtml)\(htmlEnd)"
webview.loadHTMLString(htmlString, baseURL: nil)
return webview
func updateUIView(_ uiView: WKWebView, context: Context)
【问题讨论】:
【参考方案1】:我有同样的要求,并没有使用 List,而是在 ScrollView 中使用 VStack,同时限制了每页加载的项目数(在我的例子中是 20 个)。 VStack 将渲染所有项目一次,当您向下和向上滚动时不会重新加载。因此,LazyVStack 也不起作用,因为它还会在滚动时重新加载其内容。
这也适用于自动调整 WebView 的大小以适应其加载的内容。为了视觉优化,我确保第一个项目在其他项目之前加载,出于某种奇怪的原因,SwiftUI 似乎以相反的顺序加载 webview 内容,从列表中的最新开始。
【讨论】:
以上是关于如何在 SwiftUI 中创建一个列表视图,每个列表项都是一个 WKWebView(我的实现非常慢并且有问题)的主要内容,如果未能解决你的问题,请参考以下文章
有没有更好的方法在 SwiftUI 中创建多列(数据表)列表视图
如何在 SwiftUI 中创建共享导航栏以在多个视图之间进行交互? [关闭]