WKWebView 在 iOS 10 中无法正确呈现
WKWebView not rendering correctly in iOS 10
我在 UITableViewCell 中有 WKWebView。 Web 视图加载请求,然后在完成加载后,我将调整 Web 视图高度的大小使其等于其内容高度,然后相应地调整 table 视图单元格高度。
Web 视图只显示适合屏幕大小的区域。当我向下滚动时,一切都是白色的。但是我看到以正确高度呈现的网络视图,点击并按住网络视图上的白色区域仍然可以看到选择。双指缩放使屏幕上显示的网页视图区域可见,但其他区域有时会变白。
它在 iOS 8 和 9 上运行良好。我创建了一个示例项目来演示此行为:
https://github.com/pawin/strange-wkwebview
打开雷达:
https://openradar.appspot.com/radar?id=4944718286815232
更新:此问题已在 iOS11
中解决
我有同样的问题 - 将 WKWebView 添加到 UITableViewCell,我通过以下步骤解决了这个问题:
1.Create 一个 UITextView 实例并将其添加到 UITableView 的 superview(UIViewControllew.view)
2.implement scrollViewDidScroll 中的代码如下:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self.xxtextView becomeFirstResponder];
[self.xxtextView resignFirstResponder];
}
这些代码可能会导致 cpu 性能开销增加,您可以通过某种方式修复它,例如我们使用临时变量作为阈值。
我不认为这是一个完美的解决方法,但它对我有用。
后来发现textview becomeFirstResponder 只是又导致了webview layout,所以直接修复即可:
CGFloat tempOffset = 0;
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (!tempOffset || ABS(scrollView.contentOffset.y - tempOffset) > ScreenHeight/2)
{
[self.wkWebView setNeedsLayout];
tempOffset = scrollView.contentOffset.y;
}
}
func reloadWKWebViewIfNeeded() {
for cell in self.tableView.visibleCells {
guard let webviewCell = cell as? WebviewCell else { continue }
// guard cell height > screen height
webviewCell.webview.reload()
}
}
override func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
guard !decelerate else { return }
self.reloadWKWebViewIfNeeded()
}
override func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
self.reloadWKWebViewIfNeeded()
}
虽然不是最好的解决方案,但至少用户可以看到其余内容
您需要在 UITableView
滚动时强制 WKWebView
布局。
// in the UITableViewDelegate
func scrollViewDidScroll(scrollView: UIScrollView) {
if let tableView = scrollView as? UITableView {
for cell in tableView.visibleCells {
guard let cell = cell as? MyCustomCellClass else { continue }
cell.webView?.setNeedsLayout()
}
}
}
我也有带 wkWebView 单元格的 uitableview。我遇到了同样的问题。但是您可以及时使用此代码解决此问题。按性能不用担心。我在 iphone 5s 上测试了这个解决方案,只有当你用可见的 web 单元格滚动 uitableView 时,它才被占用 10-15% CPU。
func scrollViewDidScroll(_ scrollView: UIScrollView) {
//TODO: Remove this fix when WKWebView will fixed
if let cell = tableView.cellForRow(at: IndexPath(row: 1, section: 0)) as? WKWebViewCell {
// Here we take our cell
cell.wkWebView?.setNeedsLayout()
// here is "magic" (where wkWebView it is WKWebView, which was
// previously added on cell)
}
}
在objective-C这就是我解决问题的方法。
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
NSArray * visibleCell = [self.tableView visibleCells];
for (CustomUITableViewCell * cell in visibleCell) {
if ([cell isKindOfClass:[CustomUITableViewCell class]]) {
[cell.wkWebView setNeedsLayout];
}
}
}
该代码将收集所有可见单元格并在用户滚动期间快速枚举setNeedsLayout
。
我在 UITableViewCell 中有 WKWebView。 Web 视图加载请求,然后在完成加载后,我将调整 Web 视图高度的大小使其等于其内容高度,然后相应地调整 table 视图单元格高度。
Web 视图只显示适合屏幕大小的区域。当我向下滚动时,一切都是白色的。但是我看到以正确高度呈现的网络视图,点击并按住网络视图上的白色区域仍然可以看到选择。双指缩放使屏幕上显示的网页视图区域可见,但其他区域有时会变白。
它在 iOS 8 和 9 上运行良好。我创建了一个示例项目来演示此行为: https://github.com/pawin/strange-wkwebview
打开雷达: https://openradar.appspot.com/radar?id=4944718286815232
更新:此问题已在 iOS11
中解决我有同样的问题 - 将 WKWebView 添加到 UITableViewCell,我通过以下步骤解决了这个问题:
1.Create 一个 UITextView 实例并将其添加到 UITableView 的 superview(UIViewControllew.view) 2.implement scrollViewDidScroll 中的代码如下:- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self.xxtextView becomeFirstResponder];
[self.xxtextView resignFirstResponder];
}
这些代码可能会导致 cpu 性能开销增加,您可以通过某种方式修复它,例如我们使用临时变量作为阈值。
我不认为这是一个完美的解决方法,但它对我有用。
后来发现textview becomeFirstResponder 只是又导致了webview layout,所以直接修复即可:
CGFloat tempOffset = 0;
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (!tempOffset || ABS(scrollView.contentOffset.y - tempOffset) > ScreenHeight/2)
{
[self.wkWebView setNeedsLayout];
tempOffset = scrollView.contentOffset.y;
}
}
func reloadWKWebViewIfNeeded() {
for cell in self.tableView.visibleCells {
guard let webviewCell = cell as? WebviewCell else { continue }
// guard cell height > screen height
webviewCell.webview.reload()
}
}
override func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
guard !decelerate else { return }
self.reloadWKWebViewIfNeeded()
}
override func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
self.reloadWKWebViewIfNeeded()
}
虽然不是最好的解决方案,但至少用户可以看到其余内容
您需要在 UITableView
滚动时强制 WKWebView
布局。
// in the UITableViewDelegate
func scrollViewDidScroll(scrollView: UIScrollView) {
if let tableView = scrollView as? UITableView {
for cell in tableView.visibleCells {
guard let cell = cell as? MyCustomCellClass else { continue }
cell.webView?.setNeedsLayout()
}
}
}
我也有带 wkWebView 单元格的 uitableview。我遇到了同样的问题。但是您可以及时使用此代码解决此问题。按性能不用担心。我在 iphone 5s 上测试了这个解决方案,只有当你用可见的 web 单元格滚动 uitableView 时,它才被占用 10-15% CPU。
func scrollViewDidScroll(_ scrollView: UIScrollView) {
//TODO: Remove this fix when WKWebView will fixed
if let cell = tableView.cellForRow(at: IndexPath(row: 1, section: 0)) as? WKWebViewCell {
// Here we take our cell
cell.wkWebView?.setNeedsLayout()
// here is "magic" (where wkWebView it is WKWebView, which was
// previously added on cell)
}
}
在objective-C这就是我解决问题的方法。
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
NSArray * visibleCell = [self.tableView visibleCells];
for (CustomUITableViewCell * cell in visibleCell) {
if ([cell isKindOfClass:[CustomUITableViewCell class]]) {
[cell.wkWebView setNeedsLayout];
}
}
}
该代码将收集所有可见单元格并在用户滚动期间快速枚举setNeedsLayout
。