我正在探索在 SwiftUI 中有效渲染 Markdown 的方法。本机和现有库存在问题,从功能不足(例如不支持表格等更复杂的元素)到让用户感到不舒服(例如不支持跨段落文本选择)。
我尝试使用的方法是使用 Ink 将 markdown 字符串渲染为 HTML,然后在 WKWebView 中渲染该 HTML。这解决了我发现的 Markdown 解决方案的缺点,但由于这个问题,它本身就很困难:
我有一个负责在 WKWebView 中渲染 HTML 的视图:
struct HtmlView: NSViewRepresentable {
var htmlString: String
//...
func makeNSView(context: Context) -> WKWebView {
let webView = WKWebView()
// Custom style sets body/document overflow: hidden to hide scrollbars
let customStyle = "..."
webView.loadHTMLString(htmlString, baseURL: nil)
return webView
}
func updateNSView(_ nsView: WKWebView, context: Context) {
// Same as above
let customStyle = "..."
nsView.loadHTMLString(fullHTML, baseURL: nil)
}
// Extra functionality to update size to fit the content in web view
}
我想将其放置在 ScrollView 中,并确保 ScrollView 负责滚动这些视图,这些视图可以多次渲染以显示各种 UI 元素:
ScrollView {
HtmlView(htmlString: markdownSnippetA)
HtmlView(htmlString: markdownSnippetB)
//etc..
}
如果用户滚动时鼠标位于 WKWebView 上,则 ScrollView 将不会滚动。我所做的一切似乎都无法改变这一点。如何确保滚动事件被 webview 忽略并仅由 ScrollView 处理?
我已经弄清楚了:
extension WKWebView {
open override func scrollWheel(with event: NSEvent) {
nextResponder?.scrollWheel(with: event)
}
}
这将有效地将滚动事件传递给下一个响应者,在本例中为 ScrollView。