SwiftUI 实战问题之 WebKit如何实现实时预览 webview
实战问题
我的 Markdown 编辑器的功能之一是实时预览,它向您显示 Markdown 文档的 Web 渲染版本。我使用一个非常幼稚的解决方案实现了这一点:一个WKWebView,它呈现通过 Markdown 解析器生成的 HTML。当您键入时,此 HTML 会重新生成很多次,因此 WKWebView 会刷新以多次渲染 HTML。虽然目前这似乎没有明显的性能影响,但它确实带来了一个主要问题:每次 web 视图刷新时,它都会滚动回顶部。当然,这是一个巨大的阻碍:如果您在编辑器窗格中完全向下滚动,那么实时预览将变得毫无用处,因为您不再看到您正在编辑的部分实时预览。我探索了很多很多很多, 对此的解决方案。我最终得到了一个最可行的解决方案,使该功能(大部分)按预期工作,我通过Twitter 线程记录了这一旅程。在这里,我将回顾一下这个线程,并就我对这个问题的有点优雅有点混乱的解决方案给出一些额外的想法。
🧵我终于找到了一个(hacky)解决方法来解决困扰我数月的编辑器应用程序的问题。我的编辑器现在有一个实时预览,可以记住您滚动到的位置。
解决方案
使用纯 SwiftUI 编写跨平台应用程序时,很难像使用 UIKit 或 AppKit 一样手动控制框架视图。SwiftUI 假定您只想要“默认”行为并为您实现它。即使使用视图修饰符也只能让你走这么远。
然而,在整个过程中,我发现了一个我以前没有使用过的 UI/NSViewRepresentable 成员:Coordinators。令人遗憾的是,协调器的官方文档很少,但其要点是它们本质上充当 SwiftUI 和底层 UI/NSView 之间的代理。它们允许您创建可以采用任意数量的协议的自定义 Coordinator 类,让您将自己注册为您采用的任何协议的委托或数据源!
当 Web 视图完成加载某些导航操作时,将调用第二个方法。在我的例子中,当视图完成加载我传递给它的任何 HTML 时。
使用这两种方法,您可以(几乎)可预测地计时 JavaScript 调用并实现效果。
我确信还有很多其他方法可以实现实时预览:我可以创建一个 SwiftUI 视图来解析 Markdown 并使用本机组件来呈现它们。从理论上讲,这将是一个完美的解决方案,但是实施起来需要大量时间——我目前没有时间。我还可以查看任意数量的实现 Web 视图或 Markdown 渲染器的第三方包。我什至可以考虑使用现已弃用的 Web 视图。在这一点上,我犹豫要不要弄乱它,因为我想完成其余的功能,这样我就可以发货并继续前进。也许重写是为了发布“2.0”版本,如果有的话。
无论哪种方式,当我本可以简单地使用 Apple 自己的 Catalyst 框架并通过 UIKit 获得我需要的所有工具时,我因使用 macOS 的本机工具和平台而受到积极惩罚,这肯定令人沮丧。即使在他们的最新框架中,它已经受到了年轻的影响,macOS 感觉就像是事后才想到的。
项目源码:
精品教程推荐
加入我们一起学习SwiftUI
QQ:3365059189
SwiftUI技术交流QQ群:518696470
教程网站:www.openswiftui.com