WKWebView не корректно отображает в iOS 10
У меня есть WKWebView внутри UITableViewCell. Запрос на загрузку веб-представления, а затем после завершения загрузки я изменю размер высоты веб-представления равным его высоте содержимого, а затем отрегулирую высоту ячейки таблицы таблицы, чтобы она соответствовала соответствующим образом.
Что произошло, веб-просмотр отображает только область, соответствующую размеру экрана. Когда я прокручиваю вниз, все бело. Но я вижу, что веб-представление с правильной высотой, нажмите и удерживайте белую область в веб-представлении, все еще видя выбор. Масштабирование с помощью пинча делает видимым область просмотра, отображаемую на экране, но другие области иногда становятся белыми.
Он отлично работает на iOS 8 и 9. Я создал образец проекта, чтобы продемонстрировать это поведение здесь:
https://github.com/pawin/strange-wkwebview
Открытый радар:
https://openradar.appspot.com/radar?id=4944718286815232
Ответы
Ответ 1
Вам нужно форсировать макет WKWebView
во время прокрутки UITableView
.
// 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()
}
}
}
Ответ 2
У меня такая же проблема - добавьте WKWebView в UITableViewCell, и я решил эту проблему следующими шагами:
1. Создайте экземпляр UITextView и добавьте его в UITableView superview (UIViewControllew.view)
2.Используйте коды в scrollViewDidScroll следующим образом:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self.xxtextView becomeFirstResponder];
[self.xxtextView resignFirstResponder];
}
Эти коды могут привести к увеличению издержек производительности процессора, вы можете исправить их каким-то образом, чтобы мы использовали временную переменную как пороговое значение.
Я не думаю, что это идеальный метод решения, но он работает для меня.
В конце концов я понял, что textview сталFirstResponder, просто вернул макет webview, поэтому вы можете просто исправить его следующим образом:
CGFloat tempOffset = 0;
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (!tempOffset || ABS(scrollView.contentOffset.y - tempOffset) > ScreenHeight/2)
{
[self.wkWebView setNeedsLayout];
tempOffset = scrollView.contentOffset.y;
}
}
Ответ 3
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()
}
Не лучшее решение, хотя, по крайней мере, пользователь может видеть остальную часть контента
Ответ 4
У меня также есть uitableview с ячейкой с wkWebView. И я стекаю с той же проблемой. Но своевременно вы можете исправить это с помощью этого кода. По производительности не беспокойтесь. Я тестировал это решение на iphone 5s, и он был взят на 10-15% CPU только при прокрутке uitableView с видимой веб-ячейкой.
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)
}
}
Ответ 5
В 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
в быстром перечислении во время прокрутки пользователя.