Отключить двойную прокрутку прокрутки на WKWebView
У меня есть пользовательская клавиатура с 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
}
(...)
6 ответов
У меня была похожая проблема, и я нашел решение. То есть удалить UITapGestureRecognizer, который отвечает за неправильное поведение.
WKWebView, точнее UIScrollView и его подпредставления, содержащиеся в WKWebView, имеют множество добавленных распознавателей жестов. Таким образом, вы можете легко перебрать все эти распознаватели в представлениях и удалить тот, который вам нужен.
Если вы хотите удалить все распознаватели двойного касания одним пальцем из веб-представления, вам необходимо выполнить поиск внутри подпредставлений вида прокрутки. Вы можете сделать следующее:
// 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)
}
}
}
}
Это должно исправить вашу проблему.
Гадкий и грязный раствор. Но, по крайней мере, это работает. Просто добавьте свой собственный 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 может начать прокрутку. Следующий подход заключается в настройке WKSelectionGranularityCharacter для WKWebViewConfiguration - это не очевидно, я должен сказать (Apple, почему вы это делаете?) Так что тогда он отлично работает на iOS8 - двойного нажатия нет, каждый жест работает, как и должно быть. Однако для iOS9 у нас плохие новости - http://www.openradar.me/23345435 Он был сломан. Так что продолжайте расследование.
Та же идея, что и там, /questions/6127394/otklyuchit-dvojnuyu-prokrutku-prokrutki-na-wkwebview/6127406#6127406, но немного более современная.
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)
}
}
}
}
Это реорганизованная версия, написанная на 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?.forEach{recognizer in
let tapRecognizer = recognizer as! UITapGestureRecognizer
if tapRecognizer.numberOfTapsRequired == 2 && tapRecognizer.numberOfTouchesRequired == 1 {
subview.removeGestureRecognizer(recognizer)
}
}
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
scrollView.subviews.forEach { subview in
subview.gestureRecognizers?.forEach { recognizer in
if let tapRecognizer = recognizer as? UITapGestureRecognizer,
tapRecognizer.numberOfTapsRequired == 2 {
subview.removeGestureRecognizer(recognizer)
}
}
}
}
Предполагая, что вы контролируете контент, который вы отображаете в этом WKWebView
, вы должны установить правильную область просмотра для него. Это, скорее всего, отключит это поведение.
Как насчет:
<meta id="viewport" name="viewport"
content="width=device-width; user-scalable=false" />