Ich suche nach einer Möglichkeit, die Vergrößerungsgeste "Zoomen zum Zoomen" auf der iOS-Implementierung von WKWebView zu deaktivieren. Es gibt eine BOOL-Eigenschaft für Vergrößerung, die für OS X verfügbar ist, aber unter iOS nicht verfügbar zu sein scheint.
WKWebView.h
#if !TARGET_OS_IPHONE
/* @abstract A Boolean value indicating whether magnify gestures will
change the web view's magnification.
@discussion It is possible to set the magnification property even if
allowsMagnification is set to NO.
The default value is NO.
*/
@property (nonatomic) BOOL allowsMagnification;
Ich habe auch versucht, die Gestenerkenner von WKWebView zu betrachten, aber das scheint ein leeres Array zu sein. Ich gehe davon aus, dass die eigentlichen Erkennungsmerkmale tiefer in die Struktur der Komponente eingebettet sind (ziemlich komplex, so wie es aussieht), und ich würde lieber nicht nach ihnen suchen, wenn überhaupt möglich.
Ich kenne mögliche Hacks, die möglicherweise das Auslösen der Geste verhindern könnten (selektive Weitergabe von Gesten an das WebView, Hinzufügen einer untergeordneten Ansicht zum Erfassen von Pinch-Gesten usw.), aber ich habe immer festgestellt, dass diese Verzögerungen in das Ereignis einführen und die Implementierung beibehalten werden sauber/hack frei wie möglich.
Sie können das Zoomen Ihrer Benutzer verhindern, indem Sie den Delegierten des UIScrollView Ihres WKWebKits festlegen und viewForZooming(in:)
wie folgt implementieren:
class MyClass {
let webView = WKWebView()
init() {
super.init()
webView.scrollView.delegate = self
}
deinit() {
// Without this, it'll crash when your MyClass instance is deinit'd
webView.scrollView.delegate = nil
}
}
extension MyClass: UIScrollViewDelegate {
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return nil
}
}
Die Antwort unten funktioniert nicht mehr in iOS 10 Beta.
Um die Zugänglichkeit auf Websites in Safari zu verbessern, können Benutzer jetzt Zoomen, auch wenn eine Website für den Benutzer ___scalable = no in .__ festgelegt ist. Sichtfenster.
WKWebView scheint das Viewport-Meta-Tag in der gleichen Weise zu respektieren wie Mobile Safari (wie erwartet). Also habe ich festgestellt, dass das Tag durch Javascript in das DOM injiziert wurde, nachdem eine Seite geladen wurde. Ich wäre dieser Lösung überdrüssig, wenn Sie nicht genau wissen, welcher HTML-Code in den Webview geladen wird. In meinem Fall lade ich HTML-Strings, sodass ich sie einfach zu dem HTML-Code hinzufügen kann, den ich mit der App ausliefe.
Um dies generisch für jede Webseite zu tun:
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
NSString *javascript = @"var meta = document.createElement('meta');meta.setAttribute('name', 'viewport');meta.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no');document.getElementsByTagName('head')[0].appendChild(meta);";
[webView evaluateJavaScript:javascript completionHandler:nil];
}
Es kann sinnvoll sein, einen Blick darauf zu werfen, welche Art von Navigation gerade abgeschlossen wurde, da nur eine neue Seite dieses Javascript ausführen muss.
Ich habe versucht, die minimumZoomScale
- und maximumZoomScale
-Eigenschaften von UIScrollView
auf 1
oder isMultipleTouchEnabled
-Eigenschaften von UIView
auf false
zu setzen oder nil
vom Aufruf von viewForZooming(in:)
von UIScrollViewDelegate
zurückzugeben, aber keiner hat funktioniert. In meinem Fall funktioniert nach mehrmaligem Ausprobieren das Folgende in meinem Fall [Getestet auf iOS 10.3]:
class MyViewController: UIViewController {
var webView: WKWebView?
override viewDidLoad() {
super.viewDidLoad()
//...
self.webView.scrollView.delegate = self
//...
}
}
extension MyViewController: UIScrollViewDelegate {
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
scrollView.pinchGestureRecognizer?.isEnabled = false
}
}
Vollständige Swift 3/iOS 10 Version von Landschafts Antwort:
import UIKit
import WebKit
class MyViewController: UIViewController, UIScrollViewDelegate {
var webView = WKWebView()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(webView)
webView.scrollView.delegate = self
}
// Disable zooming in webView
func viewForZooming(in: UIScrollView) -> UIView? {
return nil;
}
}
Die nativen Lösungen funktionierten nicht für mich und das Injizieren von JS ist nicht ideal. Ich habe bemerkt, dass der pinchGestureRecognizer aktiviert ist, wenn ein Zoom auftritt und mein Delegat aufgerufen wird, obwohl ich ihn beim Initialisieren der Webansicht deaktiviert habe. Um dieses Problem zu beheben, habe ich es deaktiviert, wenn ein Zoom beginnt:
extension ViewController: UIScrollViewDelegate {
// disable zooming in webview
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
scrollView.pinchGestureRecognizer?.isEnabled = false
}
}
Vollständiger Arbeitscode zum Deaktivieren des Zoomens in WkWebView in Swift
import UIKit import WebKit
klasse ViewController: UIViewController, WKUIDelegate {
// @IBOutlet var eventWkWebView: WKWebView!
var webView : WKWebView!
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration:webConfiguration)
webView.uiDelegate = self
let source: String = "var meta = document.createElement('meta');" +
"meta.name = 'viewport';" +
"meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no';" +
"var head = document.getElementsByTagName('head')[0];" + "head.appendChild(meta);";
let script: WKUserScript = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
webView.configuration.userContentController.addUserScript(script)
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// view.addSubview(eventWkWebView)
let myUrl = URL(string: "https://www.google.com")
let myRequest = URLRequest(url: myUrl!)
webView.load(myRequest)
}
}
Falls Sie eine lokale HTML-Datei anzeigen, können Sie diese HTML-Datei einfach ändern und dieses Meta-Tag in Ihre HTML-Datei einfügen:
<head>
<meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' name='viewport' />
</head>
Sie können dazu UIScrollViewDelegate verwenden. Weisen Sie zunächst in viewDidLoad () oder einer anderen geeigneten Methode einen Delegaten zu:
class LoginViewController: UIViewController, WKUIDelegate, UIScrollViewDelegate {
override func viewDidLoad() {
webView.scrollView.delegate = self
}
//And add this delegate method in your controller:
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
scrollView.pinchGestureRecognizer?.isEnabled = false
scrollView.panGestureRecognizer.isEnabled = false
}
}
Swift 2.0
extension WKWebView {
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return nil
}
}
so habe ich den Zoom für Swift3 View Controller für One-Webview-Only-App deaktiviert
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate, UIScrollViewDelegate {
@IBOutlet var webView: WKWebView!
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
webView.scrollView.delegate = self
}
func viewForZooming(in: UIScrollView) -> UIView? {
return nil;
}
}
Wenn es nicht wichtig ist, dass Sie mit Links in html umgehen (sagen Sie, dass Sie nur Text anzeigen möchten), ist es am einfachsten, die Benutzerinteraktion zu deaktivieren webView.userInteractionEnabled = false
Deaktivieren Sie das Doppeltippen, um die Geste zu vergrößern, indem Sie die Gestenerkennung fehlschlagen lassen. Dadurch wird verhindert, dass der Browser reagiert, wenn der Benutzer doppelt antippt.
import UIKit
class DisableDoubleTapRecognizer : UITapGestureRecognizer, UIGestureRecognizerDelegate{
override init(target: Any?, action: Selector?) {
super.init(target: target, action: action)
}
init() {
super.init(target:nil, action: nil)
self.numberOfTapsRequired = 2;
self.delegate = self;
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true;
}
}
//in your view controller
override func viewDidLoad() {
super.viewDidLoad()
webView.addGestureRecognizer(DisableDoubleTapRecognizer())
}
Ich habe nicht genug Ansehen, um Antworten hinzuzufügen, aber ich wollte erwähnen, dass Kevins Lösung (Meta Viewport) in iOS 10 Beta nicht mehr funktioniert. Landschafts Lösung funktioniert aber für mich!
Da die JS-Lösung W3C-Standards verwendet, sollte sie immer unterstützt werden.
Ah, Kevin, ich wünschte, so würden diese Dinge funktionieren.
Mehr hier: https://stackoverflow.com/a/37859168/1389714
Ein einfacher Weg, um das Zoomen zu verhindern
override func viewDidLoad() {
super.viewDidLoad()
webView.scrollView.delegate = self
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
scrollView.setZoomScale(1.0, animated: false)
}
Hier ist eine etwas modifizierte Version von Gulshan Kumar 's Antwort, die in iOS 12.1.2 für mich funktioniert hat und auch das Zoomen durch Doppeltippen und Drehen verhindert. In meinem Beispiel füge ich das Skript einfach direkt in die Webansicht ein. Ich habe die Skalierung auf 60% eingestellt, und es ist keine Verkettung erforderlich, um die Quellzeichenfolge aufzubauen.
let source = "var meta = document.createElement('meta'); meta.name = 'viewport'; meta.content = 'width=device-width, initial-scale=0.6, maximum-scale=0.6, user-scalable=no'; var head = document.getElementsByTagName('head')[0]; head.appendChild(meta);"
let script = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
webView.configuration.userContentController.addUserScript(script)
Wenn es besser ist, den Pinch-Zoom zu deaktivieren, wenn das Laden der Webseite abgeschlossen ist, kann auch angegeben werden, welche bestimmte URL deaktiviert werden soll
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
if let url = webView.url, url.absoluteString == "***" {
webView.scrollView.pinchGestureRecognizer?.isEnabled = false
}
print("finish")
}
Wir müssen den Delegatenanruf mit folgenden Signaturen in XCode 8 ändern:
func viewForZooming überschreiben (in scrollView: UIScrollView) -> UIView? { nil zurückgeben }
Wenn der Webview-Benutzer nur für Lesezwecke dient, d
webView.isUserInteractionEnabled = false
Dadurch funktioniert die Zoom-Geste nicht.