webentwicklung-frage-antwort-db.com.de

Deaktivieren Sie die Vergrößerungsgeste in WKWebView

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.

47
Kevin

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
    }
}
70
Landschaft

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. 

38
Kevin

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
   }
}
20
yohannes

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;
    }
}
14
Simon Epskamp

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
    }
}
12
pulse4life

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)

}

}

9
Gulshan Kumar

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>
4
Leszek Szary

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
  }
}
3
Yakup Ad

Swift 2.0

extension WKWebView {
    func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
        return nil
    }
}
3
quemeful

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;
    }    

}
2

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

1
lvp

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())
    }

1
user3543806

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

1
mark

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)
}
0
Waqar Ahmed

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)
0
Scott Gardner

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")
} 
0
Jin

Wir müssen den Delegatenanruf mit folgenden Signaturen in XCode 8 ändern:

func viewForZooming überschreiben (in scrollView: UIScrollView) -> UIView? { nil zurückgeben }

0
Brianster

Wenn der Webview-Benutzer nur für Lesezwecke dient, d

webView.isUserInteractionEnabled = false

Dadurch funktioniert die Zoom-Geste nicht.

0
Sameer Bhide