将UIWebView转换为具有dynamic大小的UITableViewCell
我有UIWebView
对象成倍数UITableViewCell
。 每个webView具有不同的大小。 原来,所有的细胞都是一样的高度。 一旦用户触摸单元格,它将展开以显示所有的webView内容。
我使用- (void) webViewDidFinishLoad:(UIWebView *)aWebView
dynamic获取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。 注意删除观察者。 无论是在didEndDisplayingCell
或viewWillDisappear
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 } }