30

I have WKWebView inside the UITableViewCell. The web view load request and then after finished loading, I'll resize the web view height to be equal to its content height, then adjust table view cell height to fit accordingly.

What happened was the web view only displays the area that fit the screen size. When I scroll down, everything is white. But I see that the web view rendered with correct height, tap and hold on the white area on the web view still see selection. Zooming with pinch makes the web view area that displaying on the screen visible, but other areas sometimes become white.

It works fine on iOS 8 and 9. I have created a sample project to demonstrate this behaviour here: https://github.com/pawin/strange-wkwebview

Open Radar: https://openradar.appspot.com/radar?id=4944718286815232

Update: This issue is resolved in iOS11

7
  • Did you solve it? i have the same problem
    – orazz
    Sep 17, 2016 at 17:20
  • I have just noticed this occurs when image in the content
    – orazz
    Sep 17, 2016 at 17:28
  • I haven't solved it yet, you saying if the website has only text, it works normally?
    – wint
    Sep 17, 2016 at 17:29
  • yes, if the website only text it works
    – orazz
    Sep 17, 2016 at 17:32
  • 1
    I have the same problem, so I replaced the tableView by collectionView, and everything works fine. Hope there are someone can figure out what's wrong with tableViewCell and WKWebView.
    – Lanford
    Oct 18, 2016 at 2:54

5 Answers 5

29

You need to force the WKWebView to layout while your UITableView scrolls.

// 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()
        }
    }
}
5
  • 3
    Please edit with more information. Code-only and "try this" answers are discouraged, because they contain no searchable content, and don't explain why someone should "try this".
    – abarisone
    Sep 19, 2016 at 14:04
  • 1
    Thank you! works for me. It looks like wkwebview doesn’t refresh the content out of the screen somehow. Anyway I am creating Apple other ticket so perhaps will be added next beta. It still fails in 10.1 beta 5. Oct 21, 2016 at 9:23
  • 1
    Wasn't it be better to run this code in scrollViewDidEndDecelerating delegate method? May 12, 2017 at 11:45
  • I was struggling to find this solution from last many days! Good job! Aug 28, 2017 at 12:13
  • Brilliant!! Dealing with webview is always pain in the ass. Jan 22, 2020 at 10:06
1
    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()
}

Not the best solution though, but at least user can see the rest of the content

1

I have the same problem - add a WKWebView to a UITableViewCell, and I solved this problem by these steps:

1.Create a UITextView instance and add it to UITableView's superview(UIViewControllew.view) 2.implement codes in scrollViewDidScroll like this:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    [self.xxtextView becomeFirstResponder];
    [self.xxtextView resignFirstResponder];
}

These codes may cause increased cpu performance overhead, you can fix it by some way such us use a temp variable as threshold value.

I don't think this is a perfect solve method, but it works for me.


Eventually I realized that textview becomeFirstResponder just led the webview layout again, so you can just fix it like this:

CGFloat tempOffset = 0;

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

In objective-C this is how I solve the problem.

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

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

That code will collect all visible cell and do the setNeedsLayout in fast enumeration during user scroll.

0

Im also have uitableview with cell with wkWebView. And i stack with same problem. But timely you can fix this with this code. By performance do not worry. I tested this solution on iphone 5s and it was taken 10-15% CPU only when you scrolling uitableView with visible web cell.

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)
   }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.