SwiftUI:WKWebView切断macOS上的页面内容(NSViewRepresentable) [英] SwiftUI: WKWebView Cutting Off Page Content on macOS (NSViewRepresentable)

查看:516
本文介绍了SwiftUI:WKWebView切断macOS上的页面内容(NSViewRepresentable)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WKWebView的基本NSViewRepresentable实现,可用于macOS上的SwiftUI应用程序. UIViewRepresentable等效项在iOS上可以正常运行,但是在macOS(本机上不是Catalyst)上,总是切断最重要的内容.

I have a basic NSViewRepresentable implementation of WKWebView, for use with SwiftUI apps on macOS. The UIViewRepresentable equivalent works fine on iOS, but on macOS (natively, not Catalyst), the top content is always cut off.

丢失的数量始终等于父视图(例如选项卡视图)及其填充的大小,这表示Web视图将其内容不断缩放为 window 的大小,而不是视图大小.

The amount lost always equals the size of parent views (such as the tab view) and their padding, which indicates that the web view keeps scaling its content to the window size, rather than the view size.

例如,此页面:

...应如下所示(如Chrome中所示).整个导航栏都被裁剪掉了(尽管侧面似乎没有受到影响).

...should be as follows (as shown in Chrome). The entire navigation bar has been cropped out (though the sides appear not to be affected).

有关如何解决此问题的任何建议?有趣的是,如果我切换回&在标签之间四次显示时,内容会正确显示约1秒钟,然后调整内容大小,以便再次将其截断.这使我认为updateNSView方法中需要一些东西,但是我不确定是什么.

Any suggestions on how to fix this? Interestingly, if I switch back & forth between tabs, the content shows correctly for ~1 second, then resizes the content so it's cut off again. This makes me think something's required in the updateNSView method, but I'm not sure what.

似乎与在此处讨论的问题类似,但那是针对基于IB的应用程序,我看不到将其应用于SwiftUI的方法.

Seems to be a similar issue to the one discussed here, but that's for IB-based apps, and I can't see a way to apply it for SwiftUI.

使用的代码如下.注意:Web视图保留为属性,因此可以由其他方法(例如触发页面加载,刷新,返回等)引用.

The code used is as follows. Note: The web view is kept as a property so it can be referenced by other methods (such as triggering page load, refresh, go back, etc.)

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()
    }
}

推荐答案

我在使用SwiftUI的MacOS应用中遇到了与WKWebView完全相同的问题.

I had the exact same issue with WKWebView in MacOS app using SwiftUI.

对我有用的解决方案是使用GeometryReader来获取确切的高度,然后将Web视图放入滚动视图中(我认为这与布局优先级计算有关,但无法达到还没有.)

The solution that worked for me is to use GeometryReader to get the exact height, and put the web view inside a scrollview (I believe it has something to do with the layout priority calculation, but couldn't get to the core of it yet).

以下是对我有用的内容的片段,也许它也将与您一起使用

Here is a snippet of what worked for me, maybe it will work with you as well

GeometryReader { g in
    ScrollView {
        BrowserView().tabItem {
            Text("Browser")
        }
        .frame(height: g.size.height)
        .tag(1)

    }.frame(height: g.size.height)
}

这篇关于SwiftUI:WKWebView切断macOS上的页面内容(NSViewRepresentable)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆