WKWebView неправильно рендеринг в iOS 10

У меня есть WKWebView внутри UITableViewCell. Запрос на загрузку веб-представления, а затем после завершения загрузки я изменю размер высоты веб-представления, чтобы он соответствовал высоте его содержимого, а затем соответствующим образом отрегулирую высоту ячейки табличного представления.

Произошло то, что веб-представление отображает только область, соответствующую размеру экрана. Когда я прокручиваю вниз, все белое. Но я вижу, что веб-вид, отображаемый с правильной высотой, нажмите и удерживайте белую область в веб-виде, и все равно увидите выделение. Масштабирование с помощью пинча делает видимой область веб-просмотра, отображаемую на экране, но другие области иногда становятся белыми.

Он отлично работает на iOS 8 и 9. Я создал пример проекта, чтобы продемонстрировать это поведение здесь: https://github.com/pawin/strange-wkwebview

Открытый радар: https://openradar.appspot.com/radar?id=4944718286815232

Обновление: эта проблема решена в iOS11

5 ответов

Решение

Вы должны заставить 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()
        }
    }
}
    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()
}

Не самое лучшее решение, но, по крайней мере, пользователь может видеть остальную часть контента

У меня та же проблема - добавить WKWebView к UITableViewCell, и я решил эту проблему с помощью следующих шагов:

1. Создайте экземпляр UITextView и добавьте его в суперпредставление UITableView(UIViewControllew.view). 2. Реализуйте коды в scrollViewDidScroll следующим образом:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    [self.xxtextView becomeFirstResponder];
    [self.xxtextView resignFirstResponder];
}

Эти коды могут привести к увеличению производительности процессора, вы можете исправить это некоторым способом, например, использовать временную переменную в качестве порогового значения.

Я не думаю, что это идеальный метод решения, но он работает для меня.


В конце концов я понял, что textviewcomeFirstResponder просто снова привел макет веб-просмотра, так что вы можете просто исправить это так:

CGFloat tempOffset = 0;

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (!tempOffset || ABS(scrollView.contentOffset.y - tempOffset) > ScreenHeight/2)
    {
        [self.wkWebView setNeedsLayout];
        tempOffset = scrollView.contentOffset.y;
    }
}

В объективе-C я так решаю проблему.

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    NSArray * visibleCell = [self.tableView visibleCells];

    for (CustomUITableViewCell * cell in visibleCell) {
        if ([cell isKindOfClass:[CustomUITableViewCell class]]) {
            [cell.wkWebView setNeedsLayout];
        }
    }
}

Этот код будет собирать все видимые ячейки и делать setNeedsLayout в быстром перечислении во время пользовательской прокрутки.

У меня также есть uitableview с ячейкой с wkWebView. И я складываю с той же проблемой. Но своевременно вы можете исправить это с помощью этого кода. По производительности не переживай. Я протестировал это решение на iphone 5s, и оно заняло 10-15% ЦП только при прокрутке 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)
   }
}
Другие вопросы по тегам