UIWebView的scalesPageToFit的WKWebView等效物是什么?

119

我正在更新我的iOS应用,将UIWebView替换为WKWebView。 然而,我不知道如何使用WKWebView实现相同的行为。 对于UIWebView,我使用scalesPageToFit确保网页显示与屏幕大小相同(以便全屏显示而无需滚动)。

我在网上找到了解决方案,但它不起作用:

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

尝试使用以下代码替换您的代码:NSString* js = @"var meta = document.createElement('meta'); " "meta.setAttribute( 'name', 'viewport' ); " "meta.setAttribute( 'content', 'width = device-width' ); " "document.getElementsByTagName('head')[0].appendChild(meta)"; [webView stringByEvaluatingJavaScriptFromString: js]; - z22
我尝试了一下,但结果还是一样的(顺便说一句,在WKWebView中不存在stringByEvaluatingJavaScriptFromString方法,所以我保留了我的evaluateJavaScript:completionHandler调用)。 - olinsha
1
你得到解决方案了吗? - anoop4real
12个回答

142

你也可以尝试使用WKUserScript。

以下是我的可用配置:

NSString *jScript = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";

WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
WKUserContentController *wkUController = [[WKUserContentController alloc] init];
[wkUController addUserScript:wkUScript];

WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
wkWebConfig.userContentController = wkUController;

wkWebV = [[WKWebView alloc] initWithFrame:self.view.frame configuration:wkWebConfig];

您可以向 WKWebViewConfiguration 添加额外的配置。


3
运作得很顺利。谢谢。 - Nithin Pai
2
对我来说非常有效 - 唯一的小调整是将WKUserScriptInjectionTimeAtDocumentEnd更改为WKUserScriptInjectionTimeAtDocumentStart。 - sckor
1
如果我将WKUserScriptInjectionTimeAtDocumentEnd更改为WKUserScriptInjectionTimeAtDocumentStart,那么对我来说它不起作用。它不会添加这个脚本。有什么原因吗? - Mahesh K
2
不错的答案,但我还想添加这个脚本以避免 Webkit 自行更改字体大小:var style = document.createElement('style');style.innerHTML = 'body { -webkit-text-size-adjust: none; }';document.getElementsByTagName('head')[0].appendChild(style); - José Manuel Sánchez
1
这个很好用。我试图使用WKWebView和自动布局对齐一个特殊的标题。从offsetHeight获取的元素高度一直太大,直到我添加了这个脚本。感谢您的帮助。 - JamWils
显示剩余12条评论

49

nferocious76的回答的翻版,用Swift代码表示:Swift 2.x 版本

let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
let userScript = WKUserScript(source: jscript, injectionTime: WKUserScriptInjectionTime.AtDocumentEnd, forMainFrameOnly: true)
let wkUController = WKUserContentController()
wkUController.addUserScript(userScript)
let wkWebConfig = WKWebViewConfiguration()
wkWebConfig.userContentController = wkUController
let youWebView = WKWebView(frame: CGRectZero, configuration: wkWebConfig)

Swift3版本

let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
let wkUController = WKUserContentController()
wkUController.addUserScript(userScript)
let wkWebConfig = WKWebViewConfiguration()
wkWebConfig.userContentController = wkUController
let yourWebView = WKWebView(frame: self.view.bounds, configuration: wkWebConfig)

27

与@nferocious76的方法类似,但使用Swift语言实现

var scriptContent = "var meta = document.createElement('meta');"
scriptContent += "meta.name='viewport';"
scriptContent += "meta.content='width=device-width';"
scriptContent += "document.getElementsByTagName('head')[0].appendChild(meta);"

webView.evaluateJavaScript(scriptContent, completionHandler: nil)

谢谢!这也解决了我的问题,使HTML字体大小变大,没有从小到大刷新。我正在使用它来“刷新”内容字体大小和内部布局。 - Nadi Hassan

19

我想出了以下解决方案:为使内容适应设备尺寸。

func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {     for making the content to fit with the device size
    let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
    webView.evaluateJavaScript(jscript)
}

1
这是唯一对我有效的方法,非常感谢。 - user2501116

14

Xamarin自定义渲染器中使用的C#版本:

string jScript = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";

WKUserScript wkUScript = new WKUserScript((NSString)jScript, WKUserScriptInjectionTime.AtDocumentEnd, true);
WKUserContentController wkUController = new WKUserContentController();
wkUController.AddUserScript(wkUScript);

WKWebViewConfiguration wkWebConfig = new WKWebViewConfiguration();
wkWebConfig.UserContentController = wkUController;
WKWebView webView=new WKWebView(Frame, wkWebConfig);

运行得非常好! - Divyesh_08
自定义渲染器是什么样子的?您是从WkWebViewRenderer继承的吗?因为ControlSetNativeControl()都是未知的... - testing
好的,看起来你需要从 ViewRenderer<CustomWebView, WKWebView> 继承并使用 OnElementChanged(ElementChangedEventArgs<CustomWebView> e) - testing
谢谢您,这确实帮助我解决了Xamarin.Forms问题,即使我根据DidFinishNavigation中的内容调整高度,HTML仍然被截断。 - Nick Peppers

13

将以下代码添加到我的HTML脚本有帮助。

<meta name="viewport" content="width=device-width, shrink-to-fit=YES">

它与 UIWebView 中的 scalePageToFit 功能相同。

参考:如何设置 iOS WkWebview 缩放比例


5

Swift 5的解决方案:

let javaScript = """
    var meta = document.createElement('meta');
                meta.setAttribute('name', 'viewport');
                meta.setAttribute('content', 'width=device-width');
                document.getElementsByTagName('head')[0].appendChild(meta);
    """

webView.evaluateJavaScript(javaScript)

2
这对我很有用,我在meta中添加了两个属性:initial-scale=1.0, shrink-to-fit=yes,它们有助于使带有大图像的html文本适应屏幕。
let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width, initial-scale=1.0, shrink-to-fit=yes'); document.getElementsByTagName('head')[0].appendChild(meta);"
        
let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)

let wkUController = WKUserContentController()
        
wkUController.addUserScript(userScript)
        
let wkWebConfig = WKWebViewConfiguration()
        
wkWebConfig.userContentController = wkUController

self.webView = WKWebView(frame: self.view.bounds, configuration: wkWebConfig)

1

这对我来说很有效,可以将图像大小适应Swift 5设备的宽度
对于来自服务器的动态HTML非常有帮助

func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
   
    let fontAdjust = "var style = document.createElement('style');style.innerHTML = 'body { -webkit-text-size-adjust: none; }';document.getElementsByTagName('head')[0].appendChild(style);"

    let imgAdjust = "var style = document.createElement('style');style.innerHTML = 'img { display: inline;height: auto;max-width: 100%; }';document.getElementsByTagName('head')[0].appendChild(style);"
webKitView.evaluateJavaScript(imgAdjust)

    webKitView.evaluateJavaScript(fontAdjust)
    webKitView.evaluateJavaScript(imgAdjust)
}


1

对我来说,这些答案都无法解决我的问题。我试图打开一个特定艺术家的亚马逊URL。原来亚马逊有一个移动响应URL和一个桌面URL。在桌面版Safari上,我更改了用户代理为iPhone(开发人员工具 > 用户代理 > Safari - iOS 13.1.3 - iPhone),并获得了适用于移动设备的正确URL。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接