Reading and writing an array in swift cause crash

205 views Asked by At

enter image description hereI am implementing wkwebviews in my tableview, where I calculate the height of tableview store it in array and reload the specific cell. But my heightForRowAt indexPath is causing crash.

var contentHeights : [CGFloat] = [400.0, 0.0, 0.0, 0.0,0.0]

I have 5 cells, height of first cell is defined, rest all 4 consists of wkwebview.

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {

            if webView.tag < self.contentHeights.count{
                let currentContentHeight = webView.scrollView.contentSize.height
                if (self.contentHeights[webView.tag] < 50.0 && self.contentHeights[webView.tag] < currentContentHeight) {
                    self.contentHeights[webView.tag] = webView.scrollView.contentSize.height
                    webView.frame = CGRect(x: webView.frame.origin.x, y: webView.frame.origin.y, width: webView.frame.width, height: currentContentHeight)
                    self.uiViewController?.reloadTableViewrow(atIndexPath: webView.tag)
                }
            }
        }
    }

func reloadTableViewrow(atIndexPath:Int){
        jobDetailTableview.reloadRows(at: [IndexPath(row: atIndexPath, section: 0)], with: .none)

    }

I assign the webview tag in cellForRowAt indexPath

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.row == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: “X1”, for: indexPath) as? X1
        if cell == nil {
            LogError.logErrorRequest(message: "nil jobInfo cell for index =  \(indexPath.row) for title = \(jobWebviewDetails[indexPath.row].name)", functionName: #function, className: "JobDetailDelegateAndDataSource", lineNumber: "\(#line)")
        }
        return cell!
    } else {
        let cell = tableView.dequeueReusableCell(withIdentifier: X2, for: indexPath)  as? X2
        cell?.selectionStyle = .none
        cell?.webview.tag = indexPath.row
        if cell == nil {
            LogError.logErrorRequest(message: "nil jobDetails cell for index =  \(indexPath.row) for title = \(jobWebviewDetails[indexPath.row].name)", functionName: #function, className: "JobDetailDelegateAndDataSource", lineNumber: "\(#line)")
        }
        return cell!
    }
}

But I am getting crash logs in HeightForRowAtIndexPath functions I tried putting logs but still no success

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if indexPath.row == 0 {
        return 340.0
    } else {
        if indexPath.row < contentHeights.count {
            return (contentHeights[indexPath.row] + 70)
        } else {
// I am getting this logs, Its running fine on 90% on devices but getting this logs for few devices
            LogError.logErrorRequest(message: "Index path = \(indexPath.row) ", functionName: #function, className: "x1", lineNumber: "\(#line)")
            return 200
        }
    }
}

I think that because I am setting and getting the array at the same time might be the reason for this problem. How to solve this problem

1

There are 1 answers

0
Xuan-Gieng Nguyen On

Forget about the crash for now, I personally don't think this is a good approach to implement your requirement.

How about letting the cells handle the height itself?

The idea is,

  1. Create a custom UITableViewCell, conform WKNavigationDelegate
  2. In the cell, implement func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!), calculate the height of the cell and update the constraint for the webView properly.
  3. In the cell, after calculating, call the viewController (as its delegate) to update the tableView using tableView.beginUpdate() and tableView.endUpdate()
  4. From View Controller, when we create the cell, let it know if it is the first cell so that it always keeps its height fixed.

That's it, no need to keep any array, no more crash!