在 iPhone X 上使 WKWebview "real" 全屏(从 WKWebView 中删除安全区域
make WKWebview "real" fullscreen on iPhone X (remove safe area from WKWebView
我正在尝试在 App WebView 中实现 "real" 全屏,这意味着无论如何我都希望网页内容完全显示在屏幕下方。
这是我目前面临的情况,在将 WebView 构建到超级视图边界时:
红色边框是 webView 的边框(也是屏幕的大小)。 Twitter 正文的高度和宽度为 100%。
我知道网站在 Safari 中不能有 100% 的宽度,它是应用程序浏览器中尊重安全区域的默认行为,但特别是在我的情况下,网页在某种程度上是为应用程序设计的,我需要使用完整的 space.
我不知道如何设置 webview 以使其内容显示完整大小。有没有办法改变安全区域?
代码片段:
private var webView : WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
self.webView = WKWebView(frame: .zero)
self.webView.layer.borderColor = UIColor.red.cgColor
self.webView.layer.borderWidth = 2
self.webView.load(URLRequest(url: URL(string: "https://www.twitter.com")!))
self.view.addSubview(self.webView)
}
override func viewDidLayoutSubviews() {
self.webView.frame = self.view.bounds
}
经过一些尝试和错误,这是我想出的解决方案。
Subclass WKWebView 并创建自定义 class。覆盖 safeAreaInsets
:
import Foundation
import WebKit
class FullScreenWKWebView: WKWebView {
override var safeAreaInsets: UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
}
改为使用 AutoLayout 约束:
NSLayoutConstraint.activate([
webView.topAnchor.constraint(equalTo: view.topAnchor),
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
webView.leftAnchor.constraint(equalTo: view.leftAnchor),
webView.rightAnchor.constraint(equalTo: view.rightAnchor)
])
记得将 viewport-fit=cover
添加到您网页的视口元标记,并使用 Safari 的新变量为您的内容添加填充,以确保它尊重安全区域。
/* iOS 11 */
constant(safe-area-inset-*);
/* iOS 11.2 */
env(safe-area-inset-*);
编辑
我也在探索在不对实际网页进行任何更改的情况下添加元标记的选项。如果我没记错的话,我确实通过 Swift 使用以下代码成功添加了元标记:
webView.evaluateJavascript("document.querySelector('meta[name=viewport]').content = document.querySelector('meta[name=viewport]').content + ', viewport-fit=cover'", completionHandler: nil)
顺便说一句,这是在WKWebView
中使用的,显然您需要在网页加载完成后执行它。还应该进行一些错误处理,因为如果缺少名为 viewport
的元标记,这将引发异常,并且如果内容开头为空,则内容将为 , viewport-fit=cover
。
您还可以从 WKWebView 扩展 safeAreaInsets。
extension WKWebView {
override open var safeAreaInsets: UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
}
对于 Objective C 试试这个代码 -
-(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (@available(iOS 11.0, *)) {
if(toInterfaceOrientation == UIInterfaceOrientationPortrait){
_webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAlways;
}else{
_webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentScrollableAxes;
}
}
}
只需在您的网页头部添加一个元元素"viewport-fit=cover"
像这样:
meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1,viewport-fit=cover"
这是另一种解决方案,无需覆盖和执行 javascript:
webView.scrollView.contentInsetAdjustmentBehavior = .never
就我而言,效果很好。
Objective-c版本:
[webView.scrollView setContentInsetAdjustmentBehavior: UIScrollViewContentInsetAdjustmentNever];
我正在尝试在 App WebView 中实现 "real" 全屏,这意味着无论如何我都希望网页内容完全显示在屏幕下方。
这是我目前面临的情况,在将 WebView 构建到超级视图边界时:
我知道网站在 Safari 中不能有 100% 的宽度,它是应用程序浏览器中尊重安全区域的默认行为,但特别是在我的情况下,网页在某种程度上是为应用程序设计的,我需要使用完整的 space.
我不知道如何设置 webview 以使其内容显示完整大小。有没有办法改变安全区域?
代码片段:
private var webView : WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
self.webView = WKWebView(frame: .zero)
self.webView.layer.borderColor = UIColor.red.cgColor
self.webView.layer.borderWidth = 2
self.webView.load(URLRequest(url: URL(string: "https://www.twitter.com")!))
self.view.addSubview(self.webView)
}
override func viewDidLayoutSubviews() {
self.webView.frame = self.view.bounds
}
经过一些尝试和错误,这是我想出的解决方案。
Subclass WKWebView 并创建自定义 class。覆盖 safeAreaInsets
:
import Foundation
import WebKit
class FullScreenWKWebView: WKWebView {
override var safeAreaInsets: UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
}
改为使用 AutoLayout 约束:
NSLayoutConstraint.activate([
webView.topAnchor.constraint(equalTo: view.topAnchor),
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
webView.leftAnchor.constraint(equalTo: view.leftAnchor),
webView.rightAnchor.constraint(equalTo: view.rightAnchor)
])
记得将 viewport-fit=cover
添加到您网页的视口元标记,并使用 Safari 的新变量为您的内容添加填充,以确保它尊重安全区域。
/* iOS 11 */
constant(safe-area-inset-*);
/* iOS 11.2 */
env(safe-area-inset-*);
编辑
我也在探索在不对实际网页进行任何更改的情况下添加元标记的选项。如果我没记错的话,我确实通过 Swift 使用以下代码成功添加了元标记:
webView.evaluateJavascript("document.querySelector('meta[name=viewport]').content = document.querySelector('meta[name=viewport]').content + ', viewport-fit=cover'", completionHandler: nil)
顺便说一句,这是在WKWebView
中使用的,显然您需要在网页加载完成后执行它。还应该进行一些错误处理,因为如果缺少名为 viewport
的元标记,这将引发异常,并且如果内容开头为空,则内容将为 , viewport-fit=cover
。
您还可以从 WKWebView 扩展 safeAreaInsets。
extension WKWebView {
override open var safeAreaInsets: UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
}
对于 Objective C 试试这个代码 -
-(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (@available(iOS 11.0, *)) {
if(toInterfaceOrientation == UIInterfaceOrientationPortrait){
_webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAlways;
}else{
_webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentScrollableAxes;
}
}
}
只需在您的网页头部添加一个元元素"viewport-fit=cover"
像这样:
meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1,viewport-fit=cover"
这是另一种解决方案,无需覆盖和执行 javascript:
webView.scrollView.contentInsetAdjustmentBehavior = .never
就我而言,效果很好。
Objective-c版本:
[webView.scrollView setContentInsetAdjustmentBehavior: UIScrollViewContentInsetAdjustmentNever];