AutoLayout constraint issue with unexpected NSAuto

2020-03-01 07:39发布

I'm using auto layout constraints programmatically and I am constantly seeing the same kind of error across my application usually related to a constraint that looks like this:

"<NSAutoresizingMaskLayoutConstraint:0x82da910 h=--& v=--& V:[UITableViewCellContentView:0x82d9fb0(99)]>"

I've put some sample code to reproduce at https://github.com/nicolasccit/AutoLayoutCellWarning

In this example, I am creating a very simple view with 2 UI elements: an image view called imageThumbnail and a label called labelName with some constraints:

"H:|-padding-[_imageThumbnail(==imageWidth)]-[_labelName]";
"V:|-padding-[_imageThumbnail(==imageHeight)]-padding-|";
"V:|-padding-[_labelName]";

On both elements I set the AutoresizingMaskIntoConstraints to NO.

And I am getting the following exception:

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:0xa6e4f90 V:[UIImageView:0xa6e4340]-(10)-|   (Names: '|':UITableViewCellContentView:0xa6e4150 )>",
    "<NSLayoutConstraint:0xa6e4f10 V:[UIImageView:0xa6e4340(80)]>",
    "<NSLayoutConstraint:0xa6e4ed0 V:|-(10)-[UIImageView:0xa6e4340]   (Names: '|':UITableViewCellContentView:0xa6e4150 )>",
    "<NSAutoresizingMaskLayoutConstraint:0xa6e4ac0 h=--& v=--& V:[UITableViewCellContentView:0xa6e4150(99)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0xa6e4f90 V:[UIImageView:0xa6e4340]-(10)-|   (Names: '|':UITableViewCellContentView:0xa6e4150 )>

I know the last constraint is related to the content view but I am unclear to properly remove it (Setting
AutoresizingMaskIntoConstraints to NO on the contentView raises an error and in the SO link below, it messes up the entire layout):

<NSAutoresizingMaskLayoutConstraint:0xa6e4ac0 h=--& v=--& V:[UITableViewCellContentView:0xa6e4150(99)]>

I've seen the answers at: Auto layout constraints issue on iOS7 in UITableViewCell but none of them seem to be working for me here.

I believe that the constraints I define are valid and pretty straightforward but can't seem to figure out what's going on. And I'm seeing the exception being raised both in iOS 6.1 and iOS 7.

Any idea what I am doing wrong here?

Thanks, Nicolas

2条回答
家丑人穷心不美
2楼-- · 2020-03-01 08:01

You should read the exception description more thoroughly:

Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints

In short, this constraint you are seeing is due to some UIView having it's translatesAutoresizingMaskIntoConstraints set to YES. In this case I would suspect this is the content view of the cell, as hinted to by UITableViewCellContentView.

You can disable it by just setting the property to NO.

cell.contentView.translatesAutoresizingMaskIntoConstraints = NO

EDIT: Now, keep in mind that this is a temporary fix, most likely you have some other logic error with your constraints, for example constraining something in the contentView of the cell to the cell itself. Or by seemingly forcing the contentView to be larger than the cell is (and therefore larger than its' automatic sizing is).

For example, is your cell tall enough? i.e is it tall enough so that the contentView is 100pt tall? Note that the contentView has to be that tall, which might not necessarily match the height of the cell.

查看更多
等我变得足够好
3楼-- · 2020-03-01 08:07

I've put a corrected version of your code at https://github.com/mattneub/AutoLayoutCellWarning. Works perfectly. This line was the main cause of your trouble:

NSString *const kImageVertical = @"V:|-padding-[_imageThumbnail(==imageHeight)]-padding-|";

Change that to

NSString *const kImageVertical = @"V:|-padding-[_imageThumbnail]-padding-|";

And all will be well.

The main reason you were having trouble is that by assigning an absolute height to the image view, you were making it impossible to also assign a height to the cell. Floating point is not exact, so you need to allow some room for the cell to grow / shrink. If we take away the absolute height, the image view gets its height from its intrinsic content size, at a lower priority, so there is no conflict.

I have some other critiques of your code. In trying to do dynamic setting of the cell's height while using auto layout, you were giving layout and constraint update commands you should never be giving, and you are giving them at wrong times. It is possible to do dynamic row heights based on constraints, but the way you're doing it is not the way. All you have to do is call systemLayoutSizeFittingSize to find out the correct cell height. Also, there is absolutely no need to put your "hidden" cell into the interface. Don't do that; it just confuses things. One of the things you'll notice when you look at my version of the code is that it is much simpler than yours, because of those differences.

For a working method, see my example at https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch08p424variableHeights/ch21p722variableHeights/RootViewController.m

And see the discussion of this issue in my book.

EDIT (May 2014): Unfortunately my answer above fails to point out one of the key causes of this problem, namely, that the cell separator has height (if it hasn't been set to None). Therefore if you assign the cell a height that doesn't take the separator height into account, the auto layout constraints, if absolute, cannot be resolved into that height. (See this answer, which really made the lightbulb come on inside my head.)

查看更多
登录 后发表回答