【问题标题】:Dynamically sized UIWebView in a UITableViewCell with auto layout - constraint violation在具有自动布局的 UITableViewCell 中动态调整大小的 UIWebView - 违反约束
【发布时间】:2014-05-28 00:28:44
【问题描述】:

我有一个UITableViewCell,其中包含一个UIWebView。表格视图单元格根据 Web 视图内容调整其高度。 我一切正常,但是当视图加载时,我在调试器中遇到约束冲突异常(应用程序继续运行并且功能正常,但如果可能,我想解决此异常)。

我是如何设置的:

TableView 像这样设置单元格高度:

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if(indexPath.section == 0) {
        [_topCell layoutIfNeeded];
        CGFloat finalHeight =  [_topCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
        return finalHeight + 1;
    }

单元格约束如下:

  1. 从单元格的 contentView(顶部)到 webView 的任意 7px 偏移
  2. Web 视图具有 62 像素的任意固定高度限制(稍后将在内容加载后展开)
  3. 从 webView 到单元格的 contentView 的任意 8px 偏移(底部)

在我的 viewDidLoad 中,我告诉 webView 去加载一个 URL,在 webViewDidFinishLoad 中,我更新了 web 视图的高度约束,像这样

-(void)webViewDidFinishLoad:(UIWebView *)webView {
    CGSize fittingSize = [webView sizeThatFits:CGSizeZero];
    // fittingSize is approx 500
    
    [self.tableView beginUpdates];

    // Exceptions happen on the following line setting the constant
    _topCell.webViewHeightConstraint.constant = fittingSize.height;

    [_topCell layoutSubviews];
    [self.tableView endUpdates];
}

异常如下所示:

Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x10964b250 V:[webView(62)]   (Names: webView:0x109664a00 )>",
    "<NSLayoutConstraint:0x109243d30 V:|-(7)-[webView]   (Names: webView:0x109664a00, cellContent:0x1092436f0, '|':cellContent:0x1092436f0 )>",
    "<NSLayoutConstraint:0x109243f80 V:[webView]-(8)-|   (Names: cellContent:0x1092436f0, webView:0x109664a00, '|':cellContent:0x1092436f0 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x10967c210 h=--& v=--& V:[cellContent(78)]   (Names: cellContent:0x1092436f0 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x10964b250 V:[webView(62)]   (Names: webView:0x109664a00 )>

这似乎有点奇怪。这意味着设置 web 视图高度的约束将被打破,但是 web 视图确实正确设置了它的高度,并且 tableview 呈现得非常好。

根据我的猜测,看起来新增加的 Web 视图高度约束(在 Web 视图加载后大约 500 像素)将与 &lt;NSAutoresizingMaskLayoutConstraint:0x10967c210 h=--&amp; v=--&amp; V:[cellContent(78)] 将单元格高度设置为 78(由界面生成器放置在那里)发生冲突。这是有道理的,但是我不希望单元格内容具有 78px 的固定高度,我希望它增加它的高度,并且在功能上,它实际上是这样做的,只是有这些例外。

  • 我尝试设置 _topCell.contentView.translatesAutoresizingMaskIntoConstraints = NO; 以尝试删除 NSAutoresizingMaskLayoutConstraint - 这会阻止异常,但随后所有其他布局都被搞砸了,Web 视图在表格视图中间高约 10 像素没有理由。

  • 我也尝试在 viewDidLoad 中设置 _topCell.contentView.autoresizingMask |= UIViewAutoresizingFlexibleHeight; 以希望影响 contentView 78px 高度约束,但这没有效果

任何帮助将不胜感激

【问题讨论】:

  • 您的[_topCell layoutSubviews]; 中有什么内容?
  • 我所做的工作与您所做的完全相同。如果您对此有解决方案,能否与我分享一些关键点?谢谢!

标签: ios objective-c uitableview uiwebview autolayout


【解决方案1】:

另一种答案,最终要简单得多:

将 webViewHeight 约束的优先级设置为非必需。运行良好,没有警告。我建议使用这个:-)

【讨论】:

    【解决方案2】:

    我想出了一个解决方案。这看起来像是一个 hack,但它可以正常工作并且不会产生错误和警告。

    诀窍是将 Web 视图的布局和高度与 contentView 分离。

    我是这样做的:

    1. 在tableviewcell中,添加一个新的UIView,名为containerView
    2. 为 Top:0 Left:0 Right:0 设置约束,但没有底部约束和高度约束
    3. 将 Web 视图(和任何其他内容)放入此 containerView
    4. 添加约束,使 Web 视图距 containerView 的顶部和底部 7 像素,并且高度约束为 62 像素

    此时,containerView 没有连接到表格视图单元格的底部,因此它可能会溢出/不足而不会抱怨自动布局。

    现在,在tableView:heightForRowAtIndexPath: 中,我们根据containerView 计算单元格高度如下:

    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        if(indexPath.section == 0) {       
            CGFloat finalHeight =  [_topCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
            return finalHeight + 1;
        }
        return [super tableView:tableView heightForRowAtIndexPath:indexPath];
    }
    

    全部完成!

    【讨论】:

      【解决方案3】:

      来自约束日志

      你想要达到的约束如下,

      在一个 78 px 的 cellContentHeight 中,您想要容纳 7(顶部空间)+ 62(Web 视图)+ 8(底部空间)的内容。这是 77(不等于 78)。两个选项中的任何一个都可以,

      1. 尝试将上边距设为 8(而不是 7)并将其设为 78。(V:|-8-[WebView(62)]-8-|)
      2. 附加到顶部,提供 8 像素顶部空间 (V:|-8-[WebView(62)]) 并且不指定 8 像素底部空间。
      3. 附加到底部,提供 8 像素底部空间 (V:[WebView(62)-8-|) 并且不指定顶部空间。

      【讨论】:

      • 是的,我同意,但是我在界面生成器中将单元格高度设置为 77。 UIKit 正在从某个地方生成内容视图 78px 约束,我不知道为什么
      猜你喜欢
      • 1970-01-01
      • 2013-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-02
      • 2017-02-20
      • 1970-01-01
      相关资源
      最近更新 更多