【问题标题】:Getting size of styled UIWebView content - Not quite working获取样式化 UIWebView 内容的大小 - 不太有效
【发布时间】:2012-07-25 00:49:03
【问题描述】:

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

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

问题描述

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

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

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

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

【问题讨论】:

    标签: ios uiwebview


    【解决方案1】:

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

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

    或者

    CGFloat newHeight = [[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.scrollHeight;"] floatValue];
    

    【讨论】:

    • javascript 代码有效。我曾尝试过其他一些 JavaScript 代码,但没有成功,但 document.body.offsetHeight; 成功了。 ScrollView 的 ContentSize 属性不起作用。我更喜欢本机代码修复(javascript 看起来很狡猾 IMO),但如果明天没有更好的答案,我会奖励你。
    • 谢谢,我同意使用 javascript 是一种肮脏的黑客行为。有更好的东西会很好......
    • 再看...它几乎有效。它比我有的要好得多,但有时视野会太小。如果我改为使用document.documentElement.scrollHeight;,那么它有时会太大。事实上,将两者取平均值会让我更接近,但偶尔还是会太大。似乎没有任何押韵或理由说明大小差异何时明显。
    • 我相信我可能已经解决了这个问题,我再次回到我之前的陈述,说你使用javascript的方法确实有效。诀窍是,当我初始化 web 视图(这是我没有在 Gist 上提供的代码)时,我将它的高度设置为 1。我在我的 webViewDidFinishLoad: 方法中这样做,但诀窍是在初始化时这样做而不是以后。感谢史蒂文的帮助,它为我指明了正确的方向。
    • death_au,你的初始化技巧太厉害了。我一直在调试这个。在初始化时,我使用的是 CGRectZero,但我无法弄清楚为什么这些 javascript 方法不起作用。谢谢!
    【解决方案2】:

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

    起初我的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 在更新 contentSize 之前更新了 webview 的 frame

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-05
      • 2015-03-07
      • 2011-07-06
      • 2013-12-10
      • 1970-01-01
      • 2014-12-28
      • 1970-01-01
      • 2023-03-30
      相关资源
      最近更新 更多