ios 在 WKWebView 中禁用放大手势
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25553711/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Disable magnification gesture in WKWebView
提问by Kevin
I'm looking for a way to disable the "pinch to zoom" magnification gesture on the iOS implementation of WKWebView. There is a magnification BOOL property available for OS X but it doesn't seem to be available on iOS.
我正在寻找一种在 WKWebView 的 iOS 实现上禁用“捏合缩放”放大手势的方法。有一个可用于 OS X 的放大 BOOL 属性,但它似乎不适用于 iOS。
WKWebView.h
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;
I've, also, tried look at the WKWebView's gesture recognizers but that seems to be turning up an empty array. I'm assuming the actual recognizers are bured deeper in the component's structure (fairly complex, by the looks of it) and would rather not go digging for them if at all possible.
我也试过查看 WKWebView 的手势识别器,但这似乎变成了一个空数组。我假设实际的识别器在组件的结构中更深(从它的外观来看相当复杂),并且如果可能的话宁愿不去挖掘它们。
I know of possible hacks that could potentially disable the gesture from firing (selectively passing gestures to the WebView, add child view to capture pinch gesture, etc) but I've always found those introduce lag into the event and want to keep the implementation as clean/hack free as possible.
我知道可能的黑客攻击可能会禁用手势触发(有选择地将手势传递给 WebView,添加子视图以捕获捏合手势等),但我总是发现那些会在事件中引入延迟并希望保持实现为尽可能干净/无黑客。
回答by Landschaft
You can prevent your users from zooming by setting the delegate of your WKWebKit's UIScrollView and implementing viewForZooming(in:)
as in the following:
您可以通过设置 WKWebKit 的 UIScrollView 的委托并按viewForZooming(in:)
如下方式实现来防止用户缩放:
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
}
}
回答by Kevin
The below answer no longer works in iOS 10 beta.
以下答案不再适用于 iOS 10 测试版。
To improve accessibility on websites in Safari, users can now pinch-to-zoom even when a website sets user-scalable=no in the viewport.
为了提高 Safari 中网站的可访问性,即使网站在视口中设置了 user-scalable=no,用户现在也可以捏合缩放。
WKWebView seems to respect the viewport meta tag the same way Mobile Safari does (as to be expected). So, I found injecting that tag into the DOM through javascript after a page load does the trick. I would be weary of this solution unless you know exactly what HTML is being loaded into the webview, otherwise I suspect it would have unintended consequences. In my case, I'm loading HTML strings, so I can just add it to the HTML I ship with the app.
WKWebView 似乎以与 Mobile Safari 相同的方式尊重视口元标记(正如预期的那样)。所以,我发现在页面加载后通过 javascript 将该标签注入到 DOM 中。我会厌倦这个解决方案,除非你确切地知道什么 HTML 正在加载到 webview 中,否则我怀疑它会产生意想不到的后果。就我而言,我正在加载 HTML 字符串,因此我可以将其添加到应用程序随附的 HTML 中。
To do it generically for any webpage:
要对任何网页进行一般性操作:
- (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];
}
It might be wise to take a look at what kind of navigation has just been completed, since only a new page will need this javascript executed.
看看刚刚完成的导航类型可能是明智的,因为只有新页面需要执行此 javascript。
回答by yohannes
I have tried setting minimumZoomScale
and maximumZoomScale
properties of UIScrollView
to 1
or isMultipleTouchEnabled
property of UIView
to false
or returning nil
from invoking viewForZooming(in:)
of UIScrollViewDelegate
but none worked. In my case, after several trial and error, the following works in my case [Tested on iOS 10.3]:
我曾尝试设置minimumZoomScale
和maximumZoomScale
属性UIScrollView
来1
或isMultipleTouchEnabled
财产UIView
来false
或返回nil
援引viewForZooming(in:)
的UIScrollViewDelegate
,但没有奏效。就我而言,经过多次反复试验,以下在我的情况下有效[在 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
}
}
回答by pulse4life
The native solutions were not working for me, and injecting JS is not ideal. I noticed that when a zoom occurs and my delegate is called, the pinchGestureRecognizer is enabled even though I disabled it when initializing the webview. To fix this, I set it to disabled whenever a zoom starts:
本机解决方案对我不起作用,注入 JS 并不理想。我注意到当发生缩放并调用我的委托时,即使我在初始化 webview 时禁用了 pinchGestureRecognizer,它也会启用。为了解决这个问题,我在缩放开始时将其设置为禁用:
extension ViewController: UIScrollViewDelegate {
// disable zooming in webview
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
scrollView.pinchGestureRecognizer?.isEnabled = false
}
}
回答by Gulshan Kumar
Complete working code to disable zooming in WkWebView in Swift.
在 Swift 中禁用 WkWebView 缩放的完整工作代码。
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate {
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()
let myUrl = URL(string: "https://www.google.com")
let myRequest = URLRequest(url: myUrl!)
webView.load(myRequest)
}
}
回答by Simon Epskamp
Full Swift 3 / iOS 10version of Landschaft's answer:
Landschaft 的完整Swift 3 / iOS 10版本的答案:
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
}
}
回答by Yakup Ad
You can use UIScrollViewDelegate for this. First assign delegate to your webview in viewDidLoad() or any other suitable method as:
您可以为此使用 UIScrollViewDelegate。首先在 viewDidLoad() 或任何其他合适的方法中将委托分配给您的 webview:
class LoginViewController: UIViewController, WKUIDelegate, UIScrollViewDelegate {
override func viewDidLoad() {
webView.scrollView.delegate = self
}
//Add this delegate method in your view controller
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
scrollView.pinchGestureRecognizer?.isEnabled = false
}
}
回答by Leszek Szary
In case you display a local html you could just modify this html and put this meta tag to your html:
如果您显示本地 html,您只需修改此 html 并将此元标记放入您的 html:
<head>
<meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' name='viewport' />
</head>
回答by quemeful
Swift 2.0
斯威夫特 2.0
extension WKWebView {
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return nil
}
}
回答by godblessstrawberry
this is how I disabled zoom for Swift3view controller for one-webview-only app
这就是我为一个 webview-only 应用程序禁用Swift3视图控制器缩放的方式
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;
}
}