Ios 在具有自动布局的UITableViewCell中动态调整UIWebView大小-约束冲突

Ios 在具有自动布局的UITableViewCell中动态调整UIWebView大小-约束冲突,ios,objective-c,uitableview,uiwebview,autolayout,Ios,Objective C,Uitableview,Uiwebview,Autolayout,我有一个UITableViewCell,其中包含一个UIWebView。“表格视图”单元根据web视图内容调整其高度。 我已经一切正常,但是当视图加载时,我在调试器中得到一个约束冲突异常(应用程序继续运行,功能正常,但如果可能的话,我想解决这个异常) 我是如何设置的: TableView按如下方式设置单元格高度: -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPat

我有一个
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;
    }
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 )>
单元约束如下所示:

-(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];
}
  • 从单元格的contentView(顶部)到webView的任意7px偏移
  • Web视图具有62px的任意固定高度约束(将在加载内容后展开)
  • 从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];
    }
    
    例外情况如下所示:

    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        if(indexPath.section == 0) {
            [_topCell layoutIfNeeded];
            CGFloat finalHeight =  [_topCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
            return finalHeight + 1;
        }
    
    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 )>
    
    无法同时满足约束。
    可能下面列表中至少有一个约束是您不想要的。试着这样做:(1)看看每个约束,试着找出你不期望的约束;(2) 找到添加了不需要的约束的代码,然后修复它。(注意:如果您看到不理解的NSAutoresizingMaskLayoutConstraints,请参阅UIView属性TranslatesAutoResizingMaskToConstraints的文档)
    (
    "",
    "",
    "",
    ""
    )
    将尝试通过打破约束进行恢复
    
    这似乎有点奇怪。这意味着设置web视图高度的约束将被打破,但是web视图确实正确设置了它的高度,并且tableview渲染得非常好


    据我猜测,新增加的web视图高度约束(在web视图加载后约为500px)似乎将与约束日志中的
    冲突

    您试图实现的约束条件如下:

    在78像素的cellContentHeight中,您希望容纳7(顶部空间)+62(网络视图)+8(底部空间)的内容。也就是77(不等于78)。两种选择中的任何一种都可以

  • 试着将上边距设为8(而不是7),并设为78。(V:|-8-[WebView(62)]-8-|)
  • 附加到顶部,提供8像素的顶部空间(V:|-8-[WebView(62)],不指定8像素的底部空间
  • 附加到底部,给8像素的底部空间(V:[WebView(62)-8-|),不指定顶部空间

  • 我想出了一个解决方案。它看起来像一个黑客,但它工作正常,不会产生错误和警告

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

    我是这样做的:

    -(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];
    }
    
  • 在tableviewcell中,添加一个新的
    UIView
    ,名为
    containerView
  • 为顶部:0左:0右:0设置约束,但不设置底部约束和高度约束
  • 将web视图(以及任何其他内容)放入此
    containerView
  • 添加约束,使web视图距离
    containerView
    的顶部和底部为7px,高度约束为62px
  • 此时,
    containerView
    未连接到表视图单元格的底部,因此它可以在没有自动布局的情况下进行上下流动

    现在,在
    tableView:heightforrowatinexpath:
    中,我们根据
    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];
    }
    

    全部完成!

    另一个答案,结果要简单得多:


    将webViewHeight约束的优先级设置为非必需的值。工作正常,没有警告。我建议您这样做:-)

    是的,我同意,但我已在interface builder中将单元格高度设置为77。UIKit正在某处生成内容视图78px约束,我无法确定您的
    [\u topCell layoutSubviews];
    ?我所做的工作与您所做的工作完全相同。如果您有解决方案,能否与我分享一些要点?谢谢!