0

这似乎是一个常见问题,但我找不到合适的解决方案。我正在尝试重新调整一堆 UIWebView 的大小以适应它们的内容,但它似乎无法正常工作。到目前为止我找到的最好的解决方案是这个 answer,但它似乎只是偶尔在我的解决方案中起作用。webViewDidFinishLoad:这个想法是在委托方法中重新调整 UIWebView 的大小。但是,这仍然没有得到正确的尺寸。如果我在之后 的某个未定义时间触发更新webViewDidFinishLoad:,则内容的大小确实正确。

我将在下面描述我的情况,并将相关来源粘贴到Gist上。

问题描述

我有一种情况,我从 JSON API 获取数据并在 webviews 中显示数据。API 返回一个对象数组,每个对象都有一个带有 HTML 格式文本的“内容”字段。设计师给出了一个结构,其中包含一个(大部分)隐藏视图,您可以向上滑动以显示该视图,其中包含所有内容的滚动视图,以非常特殊的方式格式化。

为了实现这一点,我有三个视图控制器:主视图控制器、在主视图控制器上向上滑动以显示的辅助视图控制器,以及显示来自 JSON API 结果的一项 html 格式内容的第三视图控制器.
二级视图控制器包含一个 UIScrollView 和一个三级视图控制器数组。每个第三视图控制器都包含一个 UIWebView 来显示 HTML 格式的内容,以及用于显示 JSON 对象的其他属性的标签。因为三级视图将显示在二级视图的 UIScrollView 内,所以三级视图的 UIWebView 需要重新调整大小以适应其内容并禁用用户交互,以防止混淆滚动视图中的滚动视图设想。

使所有这些工作的过程如下:

  1. 首先,在主控制器 ViewDidLoad 上,加载并显示辅助视图和活动指示器,以便 UI 不会出现冻结
  2. 接下来,从 JSON API 加载数据
  3. 当来自 API 的数据已加载(通过委托通知)时,构造第三视图控制器,从加载的数据中设置它们的属性并将它们添加到辅助控制器的列表中。
  4. 完成后,调用辅助控制器的设置方法。该方法循环遍历三级控制器列表并依次调用它们的设置方法
  5. 每个第三级控制器的设置方法设置标签的文本,并使用loadHTMLString:预定义的 html 文件的内容设置 UIWebView 的内容,并替换为 JSON 对象的内容。
  6. 在三级控制器的webViewDidFinishLoad:委托方法上,使用此答案中的方法,根据内容大小重新调整 Web 视图的大小。
  7. 重新调整第三级控制器视图的大小以适合 Web 视图并定位位于 Web 视图下方的任何标签
  8. 第三个控制器然后调用一个委托方法来通知第二个控制器它已经完成加载。二级控制器密切关注其第三级控制器中的哪些已完成加载。
  9. 当所有三级控制器完成加载后,二级控制器循环遍历其列表并将三级视图添加到它的 UIScrollView 的内容中,同时调整框架和内容高度。
4

2 回答 2

6

如果您使用的是 iOS 5.0,您可能会使用 webview.scrollView.contentsize,否则您也可以通过 javascript 获取内容大小。

CGFloat newHeight = [[webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight;"] floatValue];

或者

CGFloat newHeight = [[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.scrollHeight;"] floatValue];
于 2012-07-30T02:49:48.670 回答
0

我知道你有一个解决方案,但我自己只是解决了这个问题,我想出了一个简单而愚蠢的答案。

起初我UIWebView只会增长,但永远不会缩小。所以我开始尝试设置框架大小,但它会尝试在一个太小的框架上滚动,所以我contentSize.height每次加载一些东西时都将其设置为 1。我的完成负载看起来像这样

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    NSLog(@"--- webViewDidFinishLoad (pre sizeToFit) webview.frame = %@", NSStringFromCGRect(_detailsWebView.frame));
    NSLog(@"--- webViewDidFinishLoad (pre sizeToFit) scrollview.contentSize = %@", NSStringFromCGSize(_detailsWebView.scrollView.contentSize));
    [_detailsWebView sizeToFit];
    NSLog(@"--- webViewDidFinishLoad (post sizeToFit) scrollview.contentSize = %@", NSStringFromCGSize(_detailsWebView.scrollView.contentSize));
    NSLog(@"--- webViewDidFinishLoad (post sizeToFit) webview.frame = %@", NSStringFromCGRect(_detailsWebView.frame));
}

但这给了我这样的输出

[8431:707] --- webViewDidFinishLoad (pre sizeToFit) webview.frame = {{20, 11}, {663, 757}}
[8431:707] --- webViewDidFinishLoad (pre sizeToFit) scrollview.contentSize = {663, 1}
[8431:707] --- webViewDidFinishLoad (post sizeToFit) scrollview.contentSize = {663, 92}
[8431:707] --- webViewDidFinishLoad (post sizeToFit) webview.frame = {{20, 11}, {663, 1}}

现在只要我的“新”内容比我的旧内容大,它就可以工作,但如果内容缩小,就会出现问题。事实证明,以某种方式sizeToFit在更新framewebview 之前更新了contentSize

我可以通过在我调用之后手动更新来解决这个问题frame,最终,我只连续调用了两次。contentSizesizeToFitsizeToFit

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [_detailsWebView sizeToFit];
    [_detailsWebView sizeToFit];
}

它有效。我不能说我对这样的解决方案很满意,并且我正在努力让它变得更好,但它可以工作并且代码非常简单。

于 2012-09-07T16:41:38.670 回答