将UIWebView转换为具有动态大小的UITableViewCell

时间:2015-02-25 02:04:30

标签: ios objective-c iphone uitableview uiwebview

我将UIWebView个对象转换为倍数UITableViewCell。每个webView都有不同的大小。最初,所有细胞都是相同的高度。用户触摸单元格后,会展开以显示所有webView内容。

我正在使用- (void) webViewDidFinishLoad:(UIWebView *)aWebView来动态获取webView高度,并- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath来调整单元格的大小。但是,webViewDidFinishLoad仅在调整大小方法后调用,因此,使用旧值为webView高度调整大小。

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

以下是将Web视图加载到每个单元格的代码:

    [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];

动态获取单元格大小:

- (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执行后调整单元格大小?

我真的很感激任何帮助!

4 个答案:

答案 0 :(得分:5)

我仍然不知道为什么会这样,但我使用以下方法解决了这个问题:

我已将[tableView beginUpdates][tableView endUpdates]指示移至webViewDidFinishLoad方法。这样,只要执行webViewDidFinishLoad,它就会正确更新单元格大小。虽然我不认为这是最好的解决方案,但它确实有效。

现在,我的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);

}

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

答案 1 :(得分:2)

防止无限循环。关键是如果你已经获得了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];

答案 2 :(得分:0)

我很好奇是否与你做事的顺序有关。您可以尝试这样做:

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

答案 3 :(得分:0)

我的工作解决方案是使用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
  }
}