我有一个基本的NSViewRepresentable
实现了WKWebView
,可用于在macOS上的SwiftUI应用程序中使用。在iOS上,等效的UIViewRepresentable
可以正常工作,但在macOS上(原生而非Catalyst),顶部内容总是被裁剪掉。
丢失的量始终等于父视图(如选项卡视图)及其填充的大小,这表明Web视图将其内容缩放到窗口大小,而不是视图大小。
例如,此页面:
...应该如下所示(在Chrome中显示)。整个导航栏已被裁剪掉(尽管似乎未受影响的两侧)。
有什么建议可以解决这个问题吗?有趣的是,如果我在选项卡之间切换时,内容会正确地显示约1秒钟,然后重新调整大小,因此再次被裁剪掉。这使我认为updateNSView
方法中需要做些修改,但我不确定需要做什么。
似乎是与此处讨论的问题类似,但那是针对IB-based应用程序的,我看不到一种适用于SwiftUI的方法。
使用的代码如下。注意:Web视图被保留为属性,以便可以通过其他方法引用它(例如触发页面加载、刷新、返回等)。
public struct WebBrowserView {
private let webView: WKWebView = WKWebView()
// ...
public func load(url: URL) {
webView.load(URLRequest(url: url))
}
public class Coordinator: NSObject, WKNavigationDelegate, WKUIDelegate {
var parent: WebBrowserView
init(parent: WebBrowserView) {
self.parent = parent
}
public func webView(_: WKWebView, didFail: WKNavigation!, withError: Error) {
// ...
}
public func webView(_: WKWebView, didFailProvisionalNavigation: WKNavigation!, withError: Error) {
// ...
}
public func webView(_: WKWebView, didFinish: WKNavigation!) {
// ...
}
public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
// ...
}
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
decisionHandler(.allow)
}
public func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if navigationAction.targetFrame == nil {
webView.load(navigationAction.request)
}
return nil
}
}
public func makeCoordinator() -> Coordinator {
Coordinator(parent: self)
}
}
#if os(macOS) // macOS Implementation (iOS version omitted for brevity)
extension WebBrowserView: NSViewRepresentable {
public typealias NSViewType = WKWebView
public func makeNSView(context: NSViewRepresentableContext<WebBrowserView>) -> WKWebView {
webView.navigationDelegate = context.coordinator
webView.uiDelegate = context.coordinator
return webView
}
public func updateNSView(_ nsView: WKWebView, context: NSViewRepresentableContext<WebBrowserView>) {
}
}
#endif
使用示例:
struct BrowserView: View {
private let browser = WebBrowserView()
var body: some View {
HStack {
browser
.onAppear() {
self.browser.load(url: URL(string: "https://stackoverflow.com/tags")!)
}
}
.padding()
}
}
struct ContentView: View {
@State private var selection = 0
var body: some View {
TabView(selection: $selection){
Text("Email View")
.tabItem {
Text("Email")
}
.tag(0)
BrowserView()
.tabItem {
Text("Browser")
}
.tag(1)
}
.padding()
}
}