【问题标题】:Scroll on button click a ScrollView/WKWebView, Swift滚动按钮单击 ScrollView/WKWebView,Swift
【发布时间】:2021-01-01 09:32:30
【问题描述】:

我正在开发 SwiftUI,但由于没有 WKWebView,我通过 UIViewRepresentable 创建了它。

这是一些代码:

func makeUIView(context: Context) -> WKWebView {

    let jsScript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"

    let userScript = WKUserScript(source: jsScript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)

    let wkController = WKUserContentController()

    wkController.addUserScript(userScript)

    let wkWebConfiguration = WKWebViewConfiguration()

    wkWebConfiguration.userContentController = wkController

    let webView = WKWebView(frame: .null, configuration: wkWebConfiguration)

    webView.translatesAutoresizingMaskIntoConstraints = false

    webView.loadHTMLString(htmlBody, baseURL: nil)
    
    return webView
}

func updateUIView(_ uiView: WKWebView, context: Context) {
    
    if let htmlBody = self.htmlBody {
        uiView.loadHTMLString(htmlBody, baseURL: nil)
    }

}

func makeCoordinator() -> Coordinator {
    Coordinator(self)
}

我需要做的是在按钮点击时滚动到它的底部。

所以在我的 SwiftUI 视图中,我有一个 @State 变量并将其传递给我的 UIViewRepresentable。

这是我尝试过的(在我的 updateUIView 中):

  if scrollWebView {
        let scrollPoint = CGPoint(x: 0, y: yourWebView.scrollView.contentSize.height - webView.frame.size.height)
        webView.scrollView.setContentOffset(scrollPoint, animated: true)
  }

但是这段代码(点击按钮)滚动到我的 WkWebView 的顶部。即使我改变了 y 的符号。它总是滚动到顶部而不是底部。

我认为我无法在我的 SwiftUI 视图中实现这一点,而且我找不到滚动到 WKWebView 底部的方法。

我也认为这种行为(因为我可以做 webView.scrollView)与 ScrollView 类似。

有什么帮助吗?

【问题讨论】:

    标签: ios swift webview uiscrollview swiftui


    【解决方案1】:

    这里是可能方法的简化演示。使用 Xcode 12 / iOS 14 测试。

    struct DemoWebView : UIViewRepresentable {
        let text: String
        @Binding var scrollToBottom: Bool
    
        func makeUIView(context: Context) -> WKWebView  {
            let webview = WKWebView()
            webview.loadHTMLString(text, baseURL:  nil)
            return webview
        }
    
        func updateUIView(_ webview: WKWebView, context: Context) {
            if scrollToBottom {
                let point = CGPoint(x: 0, y: webview.scrollView.contentSize.height - webview.frame.size.height)
                webview.scrollView.setContentOffset(point, animated: true)
                DispatchQueue.main.async {
                    self.scrollToBottom = false   // turn it back for reuse
                }
            }
        }
    }
    

    和类似的用法

    @State private var scroll = false
    
    var body: some View {
        VStack {
            Button("Bottom") { self.scroll = true }
            DemoWebView(text: self.htmlText, scrollToBottom: $scroll)
        }
    }
    

    【讨论】:

    • 非常感谢您的回答!你给了我希望,相信这是可能的。但是(我的错)我从 makeUIView 中省略了一些代码。我认为这并不重要。我需要注入一些 JS 以缩放到我的 HTML 的设备大小。通过这样做,您的代码和我的代码都无法正常工作。 (如果我删除它,它的工作原理!!)。这怎么可能?我的意思是JS与我们的WebView定位无关! (我还有一个卷轴和所有相同的东西,但放大了!)
    • 我用代码更新了我的问题。我很抱歉没有报告它。
    • 我补充说:我已经尝试了在 UIKit 视图中滚动底部的相同代码(使用 JS 注入!)并且它正在工作!我们正在讨论我在此 UIViewRepresentbale 中报告的相同代码。
    • 与你的 JS 一起工作得很好。你不会忘记从updateUIView 中删除uiView.loadHTMLString(htmlBody, baseURL: nil) 吗?
    猜你喜欢
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-17
    • 1970-01-01
    相关资源
    最近更新 更多