麻烦自动版式上的UITableViewCell [英] Trouble with AutoLayout on UITableViewCell

查看:144
本文介绍了麻烦自动版式上的UITableViewCell的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在上 X code 5 项目,自动布局的麻烦。我使用的是普通视图控制器内部进行导航控制器。我有一个的MKMapView 的上半部分和一个的UITableView 的下半部分。我使用故事板,并配置了原型的UITableViewCell ,但我加入到code中的制约因素。我有双重检查原型每个控制并没有看到有配置的任何约束。当我添加的约束为的UITableViewCell 出现我的问题。我在细胞中的以下code:

I'm having trouble with autolayout on an xcode 5 project. I am using a plain view controller inside with a navigation controller. I have a MKMapView on the top half and a UITableView on the bottom half. I am using storyboards, and have configured the prototype UITableViewCell, but I am adding the constraints through code. I have double-checked every control in the prototype and don't see any constraints configured there. My problem occurs when I add the constraints for the UITableViewCell. I have the following code in the cells:

-(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行触发。如果我只是继续通过这些话,最终一切都显示为它应该是,因为它看起来像X code为选择打破了正确的约束:

I am getting the following in the debugging console. The exception is triggered by the first addConstraints line. If I just continue through those then eventually everything shows up as it should be, as it looks like xcode is choosing to break the correct constraint:

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点。这就是原型大致位置(如果我的原型移动它,我看到在调试控制台约束的变化),但我自己的图像视图和标签之间的标准距离的约束冲突。

The third NSIBPrototypingLayoutConstraint shows 78 points between the edge of the view and a label. That is where the prototype is positioned roughly (and if I move it in the prototype, I see the change in the constraint in the debugging console), but that conflicts with my own constraint of "standard" distance between the image view and the label.

我曾尝试在设定 translatesAutoresizingMaskIntoConstraints = NO 视图控制器的的cellForRowAtIndexPath ,但这似乎并没有是帮助无论是。我怎样才能修复布局?

I have tried setting the translatesAutoresizingMaskIntoConstraints=NO in the view controller's cellForRowAtIndexPath, but that doesn't seem to be helping either. How can I fix the layout?

推荐答案

有几件事情在这里介绍:

A few things to cover here:


  1. 你正在运行到(那是造成异常)的 NSIBPrototypingLayoutConstraint 约束自动生成由Interface Builder为了使你的故事板或XIB视图布局无歧义。它是pretty偷偷摸摸关于这样做,但它的自动添加必需的,这样每个暧昧视图的位置和大小被完全指定的最小限制。这是根据X code 4的变化,因为在X $ C $的C 4,你不能有模棱两可的布局在Interface Builder。随着X code 5,以后你可以,但是IB将您的布局是在编译时暧昧自动生成这些约束你。

  1. The NSIBPrototypingLayoutConstraint constraints that you're running into (and that are causing exceptions) are auto-generated by Interface Builder in order to make your Storyboard or XIB view layout non-ambiguous. It's pretty sneaky about doing this, but it's automatically adding the minimum constraints required so that the position and size of each ambiguous view becomes fully specified. This is a change from Xcode 4, because in Xcode 4 you could not have ambiguous layouts in Interface Builder. With Xcode 5 and later you can, however IB will auto-generate these constraints for you if your layout is ambiguous at compile time.

要解决这个问题的方法是添加在Interface Builder所需的最低限制,使每个视图的位置和放大器;大小完全指定,然后选择每一种不必要的限制,转到右侧栏属性检查器中,然后选中旁边的占位符 - 在构建时删除

The way to fix this issue is to add the minimum required constraints in Interface Builder so that each view's position & size is fully specified, then select each of these unwanted constraints, go to the right sidebar Attributes inspector, and check the box next to Placeholder - Remove at build time.

这不仅复选框删除您添加约束,但最重要的是将prevent采取它的地方自动生成的IB约束! (你可以想象,这是相当繁琐的,当你有一些意见,IB,并希望管理code所有的约束条件。出于这个原因,你可能希望避免使用IB完全在您打算视图层次以编程方式实现自动布局)。

Not only does this checkbox remove the constraint you added, but most importantly it will prevent the auto-generated IB constraint from taking its place! (As you can imagine, this is quite tedious when you have a number of views in IB and want to manage all your constraints in code. For this reason you may want to avoid using IB entirely for view hierarchies in which you intend to implement Auto Layout programmatically.)

什么是占位符约束和卸载约束之间的区别?下面是从我自适应自动布局交谈(视频)(的 PDF幻灯片的)两相比较:

What is the difference between a Placeholder constraint and an Uninstalled constraint? Here's a slide from my Adaptive Auto Layout talk (video) (PDF slides) comparing the two:

updateConstraints ,你不想删除约束和像你有没有重新添加。为什么不?从本质上讲,这是可怕的性能,我已经与苹果公司的工程师证实,这不是一个好主意。请参阅<一个href=\"http://stackoverflow.com/questions/18746929/using-auto-layout-within-uitableviewcell-for-dynamic-cell-layouts\">question/answer我在这里了解一些更多的细节公布,以及本回答。为了prevent限制被多次添加,使用一个布尔标志(如 hasSetupConstraints ),您设置为YES,一旦你已经设置了约束在第一时间,如果 updateConstraints 再次调用你可以立即返回,如果你没有新的限制增加。请参见进一步讨论这个问题

In updateConstraints, you don't want to remove constraints and re-add them like you have there. Why not? Essentially, it's terrible for performance, and I have confirmed with Apple engineers that this is not a good idea. See the question/answer I have posted here for some more details, as well as this answer. In order to prevent constraints being added more than once, use a boolean flag (e.g. hasSetupConstraints) that you set to YES once you have set up your constraints the first time, and if updateConstraints is called again you can just return immediately if you have no new constraints to add. See this question for further discussion.

你使用删除限制可能不完全相同的code。这是因为 [查看removeConstraints:view.constraints] 只会删除已添加到视图限制 - 记该约束可以被添加到他们的约束任何意见的SuperView通用 - 并添加到视图的限制可能不会影响布局的唯一的查看!如果您需要删除一些限制,你应该存储到每个这些约束在属性上(如含NSLayoutConstraint情况下,一个NSArray属性),然后关闭/上使用NSLayoutConstraint或API的the PureLayout开源库。你应该仅停用/因为它是计算昂贵这么做除去少限制越好。在另一方面,改变了的任何约束是非常有效的,鼓励的,你不需要删除或重新添加约束来做到这一点。

The code you're using to remove constraints may not work completely. This is because [view removeConstraints:view.constraints] will only remove constraints that have been added to view -- remember that constraints can be added to any common superview of the views they constrain -- and the constraints added to view may not be the only ones affecting the layout of view! If you need to remove a number of constraints, you should store a reference to each of those constraints in a property (e.g. an NSArray property containing NSLayoutConstraint instances), and then deactivate/remove those constraints using the API on NSLayoutConstraint or the PureLayout open-source library. You should only deactivate/remove as few constraints as possible because it is computationally expensive to do so. On the other hand, changing the constant of any constraint is very efficient and encouraged, and you don't need to remove or re-add the constraint to do that.

这篇关于麻烦自动版式上的UITableViewCell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆