ios - 使用NSAutoresizingMaskLayoutConstraint进行UITableViewCell舍入错误,但是在Storyboard和heightForRowAtIndexPath中正确设置了大小:

标签 ios objective-c uitableview autolayout

我正在尝试使用AutoLayout在我的表格视图单元格中配置子视图,在理想情况下,希望表格视图单元格尽可能高以包含所有子视图。但是,这似乎是不可能的,因为在实际创建像元之前就确定了像元的高度。

因此,到目前为止,我只是查看了设置的约束条件并计算了包含所有内容所需的总高度,并将其在情节提要中设置为该特定TableViewCell原型单元格的行高,并且还在tableView:heightForRowAtIndexPath:方法中返回了此高度。

现在,我的表格视图单元格如下所示(情节提要的屏幕截图):

有两个没有显示大小的约束,它们都具有大小10(按钮顶部容器视图以及滑块和中间标签之间的距离)。

从上到下的距离为:

  • 10(距离)
  • 50(按钮的高度)
  • 20(距离)
  • 20(标签的高度)
  • 10(距离)
  • 30(滑块的高度)
  • 20(距离)

  • 导致总高度为160。

    这正是我在此单元格的检查器中设置的:

    但是从第一个屏幕截图中可以看到,Interface builder抱怨约束是冲突的(这就是为什么它们显示为红色)。如果我将高度设置为161,IB会感到满意,但这是错误的。

    另外,如果这样做,由于约束冲突,我会在运行时得到异常:
    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:0x8d80240 V:[UISlider:0x8d81190(30)]>",
    "<NSLayoutConstraint:0x8d833e0 V:[UILabel:0x8d83300(20)]>",
    "<NSLayoutConstraint:0x8d83750 V:[UIButton:0x8d83600(50)]>",
    "<NSLayoutConstraint:0x8d85050 V:|-(10)-[UIButton:0x8d83600]   (Names: '|':UITableViewCellContentView:0x8d80ef0 )>",
    "<NSLayoutConstraint:0x8d851d0 V:[UILabel:0x8d83300]-(10)-[UISlider:0x8d81190]>",
    "<NSLayoutConstraint:0x8d85200 V:[UISlider:0x8d81190]-(20)-|   (Names: '|':UITableViewCellContentView:0x8d80ef0 )>",
    "<NSLayoutConstraint:0x8d85320 V:[UIButton:0x8d83600]-(20)-[UILabel:0x8d83300]>",
    "<NSAutoresizingMaskLayoutConstraint:0x8d8b7a0 h=--& v=--& V:[UITableViewCellContentView:0x8d80ef0(161)]>"
    

    )

    最后一个是我没有明确设置的唯一一个,但它似乎是由情节提要中的行高设置生成的,因为我的tableView:heightForRowAtIndexPath:方法返回160:
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.row == self.fetchedItemSetsController.fetchedObjects.count - 1)
        {
            return 160;
        }
        return 44;
    }
    

    (目前,我一直希望最后一个单元格是大而特殊的单元格)

    因此,好吧,当我将行高设置为160时,IB会抱怨,但是当我将行高设置为161时,运行时就会抱怨。因此,我尝试忽略IB,并将情节提要中的行高也设置为160(如第二个屏幕截图所示)。在这种情况下,我会得到相同的错误消息,但有一点点不同:
    "<NSLayoutConstraint:0x17809ce80 V:[UISlider:0x125613660(30)]>",
    "<NSLayoutConstraint:0x1782814f0 V:[UILabel:0x125615100(20)]>",
    "<NSLayoutConstraint:0x178281a90 V:[UIButton:0x125615b50(50)]>",
    "<NSLayoutConstraint:0x178281b80 V:|-(10)-[UIButton:0x125615240]   (Names: '|':UITableViewCellContentView:0x178161980 )>",
    "<NSLayoutConstraint:0x178281c20 UIButton:0x1256157b0.height == UIButton:0x125615240.height>",
    "<NSLayoutConstraint:0x178281d10 UIButton:0x1256157b0.height == UIButton:0x125615980.height>",
    "<NSLayoutConstraint:0x178281e00 V:[UILabel:0x125615100]-(10)-[UISlider:0x125613660]>",
    "<NSLayoutConstraint:0x178281e50 V:[UISlider:0x125613660]-(20)-|   (Names: '|':UITableViewCellContentView:0x178161980 )>",
    "<NSLayoutConstraint:0x178281f40 UIButton:0x125615980.height == UIButton:0x125615b50.height>",
    "<NSLayoutConstraint:0x178282030 V:[UIButton:0x125615240]-(20)-[UILabel:0x125615100]>",
    "<NSAutoresizingMaskLayoutConstraint:0x178283340 h=--& v=--& V:[UITableViewCellContentView:0x178161980(159.5)]>"
    

    现在,表格视图单元格的高度限制是159.5,而不是160。我在之前也遇到过160.5,它具有相同的情节提要设置,但是我不确定它来自哪里。

    因此,首先我以为这只是IB中的一个显示错误,但现在看来它似乎在创建错误的约束。它使用160.5(或159.5)而不是我指定的160创建约束。 为什么?我该怎么办?

    顺便说一句:单元格似乎可以正确显示,但是我再次怀疑我能否看到0.5点的差异。主要是,我想摆脱异常,因为它们使调试变得更加困难,但是我也想知道这里发生了什么。

    更新:
    159.5并不是仅仅因为我刚刚注意到的情节提要设置,而是情节提要设置和tableView:heightForRowAtIndexPath:的返回值的奇怪组合。
    以下是根据情节提要板高度(sb)设置和tableView:heightForRowAtIndexPath:方法的返回值(方法)所生成的autoresizingmasklayoutconstraint高度的一些示例。在所有情况下,子视图的约束都应导致高度为160,并且不得更改。
  • 160(sb)和160(方法):159.5(约束)
  • 161(sb)和160(方法):159.5(约束)
  • 160(sb)和161(方法):160.5(约束)
  • 162(sb)和161(方法):162(约束)
  • 161(sb)和162(方法):161(约束)
  • 162(sb)和162(方法):162(约束)

  • 所以我认为,好的,因为(6.)他们都同意,我将标签的高度设为22,所以根据子视图的总高度也将为162。结果:

    6a。 162(sb)和162(方法),162(子视图的总高度):161.5(约束)

    什么?!

    有什么想法吗?

    更新2
    我提供了一个示例项目,该项目再现了问题on Github

    最佳答案

    Separator弄乱了contentView的高度,要么应该禁用它(如果需要,可以用自定义的替换),以便contentView的高度与cell的高度匹配,或者应该考虑到contentView的高度,将约束更改为更灵活与cell的高度不匹配。两者都做会更好。

    关于ios - 使用NSAutoresizingMaskLayoutConstraint进行UITableViewCell舍入错误,但是在Storyboard和heightForRowAtIndexPath中正确设置了大小:,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22539994/

    相关文章:

    iOS Facebook 获取好友列表

    ios - Firebase 登录的授权错误列表

    objective-c - UITableview 部分(Xcode 4.5 和 iOS6)

    ios - 尝试在表格 View 中按日期对核心数据对象进行排序

    ios - UITableViewCell 中的 UICollectionView

    ios - UITableViewCell 失去突出显示的选择

    ios - Apple iPhone - 使用控制台调试 - <private>?

    ios - WKWebView 在 iPad 上水平滚动

    ios - 在 Xcode Swift 中访问 HealthKit 计步器数据

    ios - UISearchController 更改 'Cancel' 按钮标题