UITableViewCell中具有动态大小的UIWebView,具有自动布局 - 约束违规

时间:2014-05-28 00:28:44

标签: ios objective-c uitableview uiwebview autolayout

我有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
  2. 的任意7px偏移量
  3. Web视图具有62px的任意固定高度约束(一旦内容加载后将扩展)
  4. 从webView到单元格的contentView(底部)
  5. 的任意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视图加载后大约为500px)与<NSAutoresizingMaskLayoutConstraint:0x10967c210 h=--& v=--& V:[cellContent(78)]设置单元格高度设置为78(由接口构建器放置) )。这是有道理的,但是我不希望单元格内容具有78px的固定高度,我希望它增加它的高度,而在功能上,它实际上是这样做的,只是有这些例外。

    • 我尝试设置_topCell.contentView.translatesAutoresizingMaskIntoConstraints = NO;以尝试删除NSAutoresizingMaskLayoutConstraint - 这会停止异常,但随后所有其他布局都搞砸了,网页视图大约是10px高表格中间无缘无故。

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

    非常感谢任何帮助

3 个答案:

答案 0 :(得分:4)

另一种答案,最终会变得更简单:

将webViewHeight约束的优先级设置为不需要的值。运作良好,没有警告。我建议这样做: - )

答案 1 :(得分:1)

我制定了一个解决方案。它似乎是一个黑客,但它正常工作,不会产生任何错误和警告。

诀窍是将网页视图的布局和高度与contentView分开。

我这样做了如下:

  1. 在tableviewcell中,添加一个名为UIView
  2. 的新containerView
  3. 为Top赋予它约束:0左:0右:0但没有底部约束,没有高度约束
  4. 将网络视图(和任何其他内容)放在此containerView
  5. 添加约束,使得网页视图距离containerView的顶部和底部为7px,高度约束为62px
  6. 此时,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];
    }
    

    全部完成!

答案 2 :(得分:0)

来自约束日志

您尝试实现的约束如下,

在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 px底部空间。
  3. 附加到底部,给出8像素的底部空间(V:[WebView(62)-8- |)并且不指定顶部空间。