【问题标题】:Unsatisfiable constraints with NSTableView when calling reloadData调用 reloadData 时使用 NSTableView 无法满足的约束
【发布时间】:2012-12-19 08:39:12
【问题描述】:

我有一个基于视图的 NSTableView,在 10.8.2 的最新版本 Xcode 中通过界面生成器以图形方式设置了表格视图的 NSTableCellView。

当我在 NSTableView 上调用 -reloadData 时,它会崩溃:

Unable to simultaneously satisfy constraints:
(
    "<NSAutoresizingMaskLayoutConstraint:0x105cb8bf0 h=--& v=--& V:[NSTableRowView:0x105ca7020(0)]>",
    "<NSAutoresizingMaskLayoutConstraint:0x10596aa30 h=--& v=-&- V:[GroupTableRowView]-(2)-|   (Names: GroupTableRowView:0x100185860, '|':NSTableRowView:0x105ca7020 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x1058d9770 h=--& v=-&- V:|-(1)-[GroupTableRowView]   (Names: GroupTableRowView:0x100185860, '|':NSTableRowView:0x105ca7020 )>"
)

Will attempt to recover by breaking constraint 
<NSAutoresizingMaskLayoutConstraint:0x10596aa30 h=--& v=-&- V:[GroupTableRowView]-(2)-|   (Names: GroupTableRowView:0x100185860, '|':NSTableRowView:0x105ca7020 )>

我无法关闭所涉及的任何视图的自动调整大小掩码转换,因为它们的约束由 NSTableView 管理。很明显,约束是冲突的,因为 NSTableRowView 不可能有 0 高度,同时仍然满足 GroupTableRowView 上指定超级视图(行视图?)之间强制填充的其他两个约束。我不确定如何解决这个问题,任何见解将不胜感激。谢谢!

更新: 我找到了解决方法。问题是,由于某种原因,在表视图上调用 -reloadData 时,NSTableRowView 被发送的帧大小为{0, 0}。我在 NSTableRowView 子类中覆盖了-setFrameSize:,并且仅在大小不是{0,0} 时将消息向上传递到响应者链。

- (void)setFrameSize:(NSSize)newSize
{
    if (!NSEqualSizes(newSize, NSZeroSize))
        [super setFrameSize:newSize];
}

要使用子类,请实现 NSTableViewDelegate 的 -tableView:rowViewForRow: 方法以返回自定义子类的实例。

- (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row
{
    id rowView = [[GroupTableRowView alloc] init];
    // configure any custom properties
    return rowView;
}

如果表格视图完全在 IB 中设计,您只需将新的 NSView 拖到表格视图中,并将其自定义类设置为 NSTableRowView 子类,并将其用户界面项标识符更改为 NSTableViewRowViewKey

【问题讨论】:

  • 凹凸。在使用基于视图的表格视图时,我遇到了类似的问题。你的问题有进展吗?
  • 我用解决方法更新了我的问题。我仍在寻找为什么要发送 NSTableCellView {0,0} 但我无法在演示应用程序中重现这一点,以便向 Apple 提交错误报告。
  • @Andrew 我认为这实际上是解决方案,谢谢!
  • @Andrew,感谢您发布此信息。我有完全相同的问题。这让我发疯,我想我不会明白这一点。
  • @Andrew,你能发布你如何子类化你的 tablerowview 吗?我没有使用任何tablerowview,但是出现了这个问题!

标签: cocoa nstableview osx-mountain-lion autolayout


【解决方案1】:

我有同样的问题,它总是让我发疯..

我已经使用您的代码解决了这个问题,但继承了 NSTableRowView 而不是 NSTableCellView。要自动让表格使用您的自定义行视图,请将自定义 NSView 添加到您的表格中。将其类设置为您的自定义行视图,重要的是,将其标识符设置为NSTableViewRowViewKey

有了这个特殊标识符,表格会自动将其用作行视图。

【讨论】:

  • 你说得对,我回去查看了我的代码,实际上我正在继承 NSTableRowView。谢谢!
【解决方案2】:

我有一个类似的问题,但列宽而不是行高。在调用reloadData 之后,基于视图的NSTableViews 的单元格上会立即弹出无法满足的自动布局约束。在我的情况下,这是由于NSTableColumn 上的最小宽度设置太小而无法包含单元格中约束的最小宽度。所以对于任何有类似问题的人,我会先验证一下。

“有趣”的部分是这只是reloadData 的问题,而不是正常布局的问题,因为NSTableView 的宽度受到限制,使其无法正常尝试创建这么小的单元格.但是当reloadData 被调用时,它显然首先创建了一个新的单元格,其框架大小设置为最小列宽,然后再调整列的大小以使其适合(如果您设置了表格来执行此操作)。所以即使看起来一切正常,它仍然会在调用reloadData 后立即吐出关于不可满足约束的错误,因为单元格视图的初始宽度对于填充来说太小了,等等。

故事的寓意是始终检查 最小 NSTableColumn 宽度对于单元格中的约束是否足够大,即使您认为该列不会那么小。 IB 使修改约束变得容易,并且在更改单元格中的某些内容后很容易忘记重新检查列宽选项。

【讨论】:

  • 非常感谢!这为我节省了数小时痛苦的调试时间。
猜你喜欢
  • 1970-01-01
  • 2012-12-28
  • 1970-01-01
  • 2014-10-27
  • 2014-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多