在 WKWebView 上禁用双击滚动
Posted
技术标签:
【中文标题】在 WKWebView 上禁用双击滚动【英文标题】:Disable double-tap scroll on WKWebView 【发布时间】:2015-10-13 20:03:33 【问题描述】:我有一个带有全宽和全高 WKWebView 的自定义键盘。我已经通过wkWebView!.scrollView.scrollEnabled = false
禁用了滚动,但在WKWebView 底部双击时我仍然有一个奇怪的滚动行为。这里是我尝试加载的简单网页的源代码:http://is.gd/gt8h2q(非常简单,只是一个带有绿色背景和一行文本的 div 全屏)。下面,一个GIF作为解释。以下是我创建 WKWebView 的方法:
class KeyboardViewController: UIInputViewController, WKScriptMessageHandler
var wkWebView: WKWebView?
override func loadView()
super.loadView()
let contentController = WKUserContentController()
contentController.addScriptMessageHandler(self, name:"callbackTestOne")
let config = WKWebViewConfiguration()
config.userContentController = contentController
self.wkWebView = WKWebView(frame:self.view.frame, configuration:config)
self.view = self.wkWebView!
override func viewDidLoad()
super.viewDidLoad()
(...)
wkWebView!.scrollView.bounces = false
wkWebView!.scrollView.scrollEnabled = false
wkWebView!.scrollView.backgroundColor = UIColor(red:248, green:248, blue:248, alpha:1)
wkWebView!.scrollView.opaque = true
wkWebView!.scrollView.showsHorizontalScrollIndicator = false
wkWebView!.scrollView.showsVerticalScrollIndicator = false
wkWebView!.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal
(...)
【问题讨论】:
仍然没有解决的问题...我找到了一个肮脏的方法来解决:在我的本地加载页面中,当滚动位置> 0时,我使用 jQuery 自动滚动到顶部。代码:$(window).scroll(function() if ( $(window).scrollTop() > 0 ) $(window).scrollTop(0); ; );
这是一个真正的问题。将 WKWebView 添加到 iMessage 应用程序或扩展程序时也会发生同样的事情。
【参考方案1】:
我遇到了类似的问题并找到了解决方案。即移除导致不当行为的 UITapGestureRecognizer。
WKWebView,或者更准确地说是 UIScrollView 及其包含在 WKWebView 中的子视图,添加了很多手势识别器。因此,您可以轻松地遍历视图中的所有识别器并删除您需要的识别器。
如果要从 webView 中删除所有单指双击识别器,则需要在滚动视图的子视图内进行搜索。您可以执行以下操作:
// iterate over all subviews of the WKWebView's scrollView
for subview in _webView.scrollView.subviews
// iterate over recognizers of subview
for recognizer in subview.gestureRecognizers ?? []
// check the recognizer is a UITapGestureRecognizer
if recognizer.isKind(of: UITapGestureRecognizer.self)
// cast the UIGestureRecognizer as UITapGestureRecognizer
let tapRecognizer = recognizer as! UITapGestureRecognizer
// check if it is a 1-finger double-tap
if tapRecognizer.numberOfTapsRequired == 2 && tapRecognizer.numberOfTouchesRequired == 1
// remove the recognizer
subview.removeGestureRecognizer(recognizer)
这应该可以解决您的问题。
【讨论】:
很好的解释!为我的情况工作 - 只允许一键式。谢谢! 这种方式适用于网页视图初始渲染。但是在你捏缩放网页后,双击手势又回来了。我还没有找到根本原因。 应该在didFinish导航后调用,否则不起作用【参考方案2】:Hacky 和肮脏的解决方案。但至少它有效。只需将您自己的 UITapGestureRecognizer 添加到包含 WKWebView 的视图中,并将您的 UIViewController 委托给此手势识别器。我使用了这段代码:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
if ([[otherGestureRecognizer description] containsString:@"WKSyntheticClickTapGestureRecognizer"] && [[otherGestureRecognizer description] containsString:@"numberOfTapsRequired = 2"])
[otherGestureRecognizer removeTarget:nil action:nil];
return YES;
更新 1 经过一番调查,我发现这种方法不太好。因为我们在长按菜单时遇到问题,尤其是在取消选择所选文本时。对我来说仍然存在问题 - 当菜单出现时长按一下,向左或向右轻轻滑动 - 有时 WKWebView 可能会开始滚动。 下一个方法是为 WKWebViewConfiguration 设置 WKSelectionGranularityCharacter - 这并不明显我必须说(Apple 你为什么要这样做?)所以它在 ios8 上工作正常 - 没有双击,每个手势都可以正常工作。但是对于 iOS9,我们有坏消息 - http://www.openradar.me/23345435 它坏了。所以继续调查。
【讨论】:
【参考方案3】:与https://***.com/a/42939172/2883860 的想法相同,但更现代一些。
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)
webView.scrollView.subviews.forEach subview in
subview.gestureRecognizers?.forEach recognizer in
if let tapRecognizer = recognizer as? UITapGestureRecognizer,
tapRecognizer.numberOfTapsRequired == 2 && tapRecognizer.numberOfTouchesRequired == 1
subview.removeGestureRecognizer(recognizer)
【讨论】:
【参考方案4】:这是重构版本,用 Swift 4.2 编写,只需将您的 WKWebView 作为参数传递并在 viewDidLoad 之类的地方调用该函数。
private func deleteDoubleTap(web: WKWebView)
for subview in web.scrollView.subviews
let recognizers = subview.gestureRecognizers?.filter$0 is UITapGestureRecognizer
recognizers?.forEachrecognizer in
let tapRecognizer = recognizer as! UITapGestureRecognizer
if tapRecognizer.numberOfTapsRequired == 2 && tapRecognizer.numberOfTouchesRequired == 1
subview.removeGestureRecognizer(recognizer)
【讨论】:
【参考方案5】:假设您可以控制在 WKWebView
中显示的内容,您应该为其设置正确的视口。这很可能会禁用此行为。
怎么样:
<meta id="viewport" name="viewport"
content="width=device-width; user-scalable=false" />
【讨论】:
是的,我尝试使用此视口。但是这个滚动问题仍然存在:s以上是关于在 WKWebView 上禁用双击滚动的主要内容,如果未能解决你的问题,请参考以下文章