ios – 在UITableViewCell上的AutoLayout的麻烦

我在xcode 5项目上遇到自动展开问题。我使用一个简单的视图控制器里面的导航控制器。我有一个MKMapView在上半部分和一个UITableView在下半部分。我使用storyboards,并配置了原型UITableViewCell,但我通过代码添加约束。我已经仔细检查了每个控件的原型,没有看到任何约束配置。我的问题发生在当我添加UITableViewCell的约束。我在单元格中有以下代码:

-(void)updateConstraints {
    [super updateConstraints];
    //first remove old constraints
    [self removeConstraints:self.constraints];
    [self.nameLabel removeConstraints:self.nameLabel.constraints];
    [self.addressLabel removeConstraints:self.nameLabel.constraints];
    [self.rentableSquareFeetLabel removeConstraints:self.rentableSquareFeetLabel.constraints];
    [self.lastSaleAmountLabel removeConstraints:self.lastSaleAmountLabel.constraints];
    [self.lastSaleDateLabel removeConstraints:self.lastSaleAmountLabel.constraints];
    [self.thumbnailImageView removeConstraints:self.thumbnailImageView.constraints];

    //then set up constraints
    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_thumbnailImageView, _nameLabel, _rentableSquareFeetLabel, _lastSaleAmountLabel, _addressLabel, _lastSaleDateLabel);
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_thumbnailImageView(60)]-[_nameLabel(<=200)]-(>=8)-[_rentableSquareFeetLabel]-(>=8)-[_lastSaleAmountLabel]|" options:0 metrics:nil views:viewsDictionary]];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_nameLabel]-(-4)-[_addressLabel]" options:NSLayoutFormatAlignAllLeading metrics:nil views:viewsDictionary]];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_lastSaleAmountLabel]-(-4)-[_lastSaleDateLabel]" options:NSLayoutFormatAlignAllLeading metrics:nil views:viewsDictionary]];
}

我在调试控制台得到以下。异常由第一个addConstraints行触发。如果我只是继续通过那些,那么最终一切都显示出来,因为它看起来像xcode正在选择打破正确的约束:

2013-09-25 15:07:14.169 PECProperties[32381:a0b] 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)  (
    "<NSIBPrototypingLayoutConstraint:0x9d56c70 'IB auto generated at build time for view with fixed frame' H:|-(0)-[UIImageView:0x9d558f0](LTR)   (Names: '|':UITableViewCellContentView:0x9d55620 )>",
    "<NSIBPrototypingLayoutConstraint:0x9d56d20 'IB auto generated at build time for view with fixed frame' H:[UIImageView:0x9d558f0(60)]>",
    "<NSIBPrototypingLayoutConstraint:0x9d56d80 'IB auto generated at build time for view with fixed frame' H:|-(78)-[UILabel:0x9d559e0](LTR)   (Names: '|':UITableViewCellContentView:0x9d55620 )>",
    "<NSLayoutConstraint:0x9d53830 H:[UIImageView:0x9d558f0]-(NSSpace(8))-[UILabel:0x9d559e0]>" )

Will attempt to recover by breaking constraint  <NSIBPrototypingLayoutConstraint:0x9d56d80 'IB auto generated at build time for view with fixed frame' H:|-(78)-[UILabel:0x9d559e0](LTR)   (Names: '|':UITableViewCellContentView:0x9d55620 )>

Break on objc_exception_throw to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

第三个NSIBPrototypingLayoutConstraint显示在视图的边缘和标签之间的78个点。这是原型定位的地方(如果我在原型中移动它,我看到调试控制台中的约束的变化),但是与我自己的约束“图像视图和标签之间的”标准“距离冲突。

我已经尝试在视图控制器的cellForRowAtIndexPath中设置translatesAutoresizingMaskIntoConstraints = NO,但这似乎没有帮助。如何修复布局?

这里有几点要介绍:

>您正在运行(并且导致异常)的NSIBPrototypingLayoutConstraint约束是由Interface Builder自动生成的,以使您的故事板或XIB视图布局不含糊。这是非常鬼祟,但它会自动添加所需的最小约束,以便每个模糊视图的位置和大小完全指定。这是从Xcode 4的一个变化,因为在Xcode 4中,你不能在Interface Builder中有歧义的布局。使用Xcode 5和更高版本,你可以,但是如果你的布局在编译时模糊不清,IB会自动为你生成这些约束。

解决这个问题的方法是在Interface Builder中添加最低要求的约束,以便每个视图的位置&大小完全指定,然后选择每个这些不需要的约束,转到右侧边栏属性检查器,并选中Placeholder – 在构建时删除旁边的框。

此复选框不仅会删除您添加的约束,而且最重要的是它将阻止自动生成的IB约束占据其位置! (你可以想象,当你在IB中有多个视图并且希望在代码中管理所有的约束时,这是相当乏味的。因此,你可能希望避免将IB完全用于要实现Auto的视图层次编程布局。)

占位符限制和卸载限制之间的区别是什么?这是从我的Adaptive Auto Layout talk (video)(PDF slides)比较两个:

>在updateConstraints中,您不想删除约束并重新添加它们,就像您在那里一样。为什么不?基本上,它的性能是可怕的,我已经确认与苹果工​​程师,这不是一个好主意。有关更多详细信息,请参阅question/answer I have posted here以及此answer.为了防止约束被添加多次,使用一个布尔标志(例如hasSetupConstraints),你设置为YES一旦你已经设置你的约束第一次,如果updateConstraints被再次调用,你可以立即返回,如果你没有新的约束添加。有关进一步讨论,请参见this question
>您用于删除约束的代码可能无法完全正常工作。这是因为[view removeConstraints:view.constraints]将只删除已添加到视图的约束 – 请记住,约束可以添加到它们约束的视图的任何公共超级视图 – 添加到视图的约束可能不是只有影响视图的布局!如果你需要删除一些约束,你应该在一个属性(例如包含NSLayoutConstraint实例的NSArray属性)中存储每个约束的引用,然后使用NSLayoutConstraint或the PureLayout open-source library上的API停用/删除这些约束。你应该仅仅去激活/去除尽可能少的约束,因为这样做是计算昂贵的。另一方面,改变任何约束的常量是非常有效和鼓励的,你不需要删除或重新添加约束来做到这一点。

http://stackoverflow.com/questions/19015215/trouble-with-autolayout-on-uitableviewcell

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:ios – 在UITableViewCell上的AutoLayout的麻烦