在 macOS 中禁用 WKWebview 的弹跳滚动

Disable bounce scrolling for WKWebview in macOS

尝试在 macOS 中禁用 WKWebview 的弹跳滚动, 但是 macOS 中的 WKWebview 没有 "scrollView"

let webView = WKWebView(frame: view.frame)
print(webView.scrollView)

你可能注意到也可能没有注意到的一个非常奇怪的事情是,在 WKWebView class 中,有一个理论上 "supposed" 的 scrollView 描述位于 class,但是 scrollView 不存在。这可以在下面的照片中看到:

我会说这可能是 Apple 的一个奇怪过程,但在 iOS class 中看到,存在相同的描述,但这次有一个实际的 scrollView:

除非我在这里遗漏了一些重要的东西,否则这可能意味着以下两种情况之一:

  1. 应该有scrollView但是没有(就是被苹果不小心删除了???)
  2. macOS 的 WKWebView 中移除了 scrollView,但是描述不小心留在了 class?

无论哪种方式,这都是一个非常奇怪的发现。

你可能想考虑对此做一些进一步的研究,也许 filing a Swift bug report

编辑:

有人向我指出,这个滚动视图实际上只是 iOS 属性,而不必要的评论就是错误。

可以通过重写 WKWebView 来禁用滚动 class:

class NoScrollWebView: WKWebView {
    override func scrollWheel(with theEvent: NSEvent) {
        nextResponder?.scrollWheel(with: theEvent)
        return
    }
}

看这里:

有同样的问题。设置 webView.scrollView.bounces = false(其中 webView 是 WKWebView)在 iOS 上有效,但在 macOS(多平台 SwiftUI 项目)上无效。

似乎可行的是使用分配给 webView.scrollView.delegate 的 UIScrollViewDelegate 实现的变通方法。不过,我还没有测试过它是否有任何副作用;我想出了一个业余爱好项目,没什么大不了的。

class WebViewUIScrollViewDelegate: NSObject, UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if (scrollView.contentOffset.y < 0) {
            // Prevent top bounce
            scrollView.setContentOffset(CGPoint(x: scrollView.contentOffset.x, y: 0), animated: false)
        } else if (scrollView.contentOffset.y >= scrollView.contentSize.height - scrollView.frame.size.height) {
            // Prevent bottom bounce
            scrollView.setContentOffset(CGPoint(x: scrollView.contentOffset.x, y: scrollView.contentSize.height - scrollView.frame.size.height), animated: false)
        } else if(scrollView.contentOffset.x < 0) {
            // Prevent left bounce
            scrollView.setContentOffset(CGPoint(x: 0, y: scrollView.contentOffset.y), animated: false)
        } else if (scrollView.contentOffset.x >= scrollView.contentSize.width - scrollView.frame.size.width) {
            // Prevent right bounce
            scrollView.setContentOffset(CGPoint(x: scrollView.contentSize.width - scrollView.frame.size.width, y: scrollView.contentOffset.y), animated: false)
        }
    }
}