将UIWebView转换为具有dynamic大小的UITableViewCell

我有UIWebView对象成倍数UITableViewCell 。 每个webView具有不同的大小。 原来,所有的细胞都是一样的高度。 一旦用户触摸单元格,它将展开以显示所有的webView内容。

我使用- (void) webViewDidFinishLoad:(UIWebView *)aWebViewdynamic获取webView的高度和- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath来调整单元格的大小。 但是, webViewDidFinishLoad仅在resize方法之后调用,因此resize是使用webView高度的旧值创build的。

我试图以所需的顺序手动调用这两种方法,但它确实有效(我不认为我应该这样做,无论如何…)。

这里是我的代码加载networking视图到每个单元格:

  [self.webView setUserInteractionEnabled:NO]; [self.webView loadHTMLString:finalString baseURL:nil]; [cell addSubview:self.webView]; cell.accessoryView = accessoryLabel; cell.textLabel.text = nil; self.selectedRowIndex = indexPath.row; [tableView beginUpdates]; [tableView endUpdates]; [tableView deselectRowAtIndexPath:indexPath animated:YES]; 

要dynamic获取单元大小:

 - (void) webViewDidFinishLoad:(UIWebView *)aWebView { CGRect frame = aWebView.frame; frame.size.height = 1; aWebView.frame = frame; CGSize fittingSize = [aWebView sizeThatFits:CGSizeZero]; frame.size = fittingSize; aWebView.frame = frame; self.cellSize = fittingSize.height; NSLog(@"Calling webViewDidFinishLoad. Cell size value: %lf", self.cellSize); } 

要更改单元格大小:

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath { if(indexPath.row == self.selectedRowIndex) { NSLog(@"Resizing cell with size: %lf", self.cellSize); return self.cellSize + 10; } return 44; } 

以下是输出结果的样子:

 2015-02-24 22:59:08.902 testProject[62200:2703641] Resizing cell with size: 0.000000 2015-02-24 22:59:09.064 testProject[62200:2703641] Calling webViewDidFinishLoad. Cell size value: 501.000000 

有没有办法只调整webViewDidFinishLoad执行后的单元格?

我真的很感激任何帮助!

我仍然不知道这是为什么,但我用下面的方法解决了它:

我将[tableView beginUpdates][tableView endUpdates]指令移到了webViewDidFinishLoad方法中。 这样,无论何时执行webViewDidFinishLoad ,它都将正确更新单元格大小。 虽然我不认为这是最好的解决scheme,但它的工作原理。

现在,我的webViewDidFinishLoad方法如下所示:

 - (void) webViewDidFinishLoad:(UIWebView *)aWebView { CGRect frame = aWebView.frame; frame.size.height = 1; aWebView.frame = frame; CGSize fittingSize = [aWebView sizeThatFits:CGSizeZero]; frame.size = fittingSize; aWebView.frame = frame; self.cellSize = fittingSize.height; [self.tableView beginUpdates]; [self.tableView endUpdates]; NSLog(@"Calling webViewDidFinishLoad. Cell size value: %lf", self.cellSize); } 

也许答案可以帮助其他有类似问题的人。

为了防止无限循环。 关键是如果你已经得到了webview的高度,只需在webViewDidFinishLoad方法中返回它。 我的webViewDidFinishLoad看起来像这样:

  // If the height is already exist, just return to prevent the infinite loop // The default height is 0.0 if ([[self.webviewHeightDic objectForKey:[NSString stringWithFormat:@"%ld",(long)webView.tag]] floatValue] != 0.0) { return; } CGRect frame = webView.frame; frame.size.height = 1; webView.frame = frame; CGSize fittingSize = [webView sizeThatFits:CGSizeZero]; frame.size = fittingSize; webView.frame = frame; NSLog(@"Cell height = %f ",fittingSize.height); // Set the height to the target webview [self.webviewHeightDic setObject:[NSNumber numberWithFloat:fittingSize.height] forKey:[NSString stringWithFormat:@"%ld",(long)webView.tag]]; // Refresh the tableView [self reloadData]; 

我很好奇,如果跟你做事的顺序有关系的话。 你可以尝试这样做:

 [cell addSubview:self.webView]; self.webView.frame = ... create frame with cell width and height set to 1 ... [self.webView loadHTMLString:finalString baseURL:nil]; 

我的工作解决scheme是使用KVO。 注意删除观察者。 无论是在didEndDisplayingCellviewWillDisappear

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) cell.webview.addObserver(self, forKeyPath: "scrollView.contentSize", options: NSKeyValueObservingOptions.New, context: &context) } override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String: AnyObject]?, context: UnsafeMutablePointer<Void>) { if let webview = object as? UIWebView { let cs = webview.scrollView.contentSize } }