Auto Layout weirdness


Ok, lets start with the solution project for chapter 15. select HomepwnerItemCell.xib in the navigator. now select the item name field, and with the size inspector, change the width to 180. Do the same with the serial number field. Now go to the file inspector, and enable the “Use Autolayout” checkbox. Now build and run. Create an entry and give it a value of 9001. The format it displays is as below, with the value out of the bounds of the cell:

Now, if you turn off autolayout, you can use the springs and such and make it look right. My question is, why is it doing this with autolayout turned on, and how do we fix it so it looks right? I’ve tried a number of tweeks to make it look right, but haven’t found the secret yet. The constraints listed in the size inspector seem to indicate that it SHOULD work, but it doesn’t. (note, changeing the width of the name and serial number labels is necessary, or else autolayout uses leading space constraints instead of the trailing space constraint.) Or is autolayout really just that useless that we should always avoid it?




It is a bug in Xcode that autolayout XIBs for UITableViewCells don’t work. (The constraints are tied to the cell and not the cell’s contentView.)

Yes, this is a massive oversight by Xcode and it really sucks. Use autoresizing masks for a table view cell that comes from a XIB and optionally add constraints in awakeFromNib.


I assume this is also the reason that if you enter edit mode the contraints fail to move everything over? As a result the thumbnail of the item overlaps with the delete indicator on the left… Is there any way to fix this without manually creating the constraints in code?


Correct, and no, the only way to circumvent the bug is to set up constraints programmatically. (Or you could set up the constraints in the XIB and then remove them from the cell and add them to the contentView, but that probably is annoying, too.)


I found this Stack Overflow answer helpful in understanding exactly what was going on, and it has an example of removing a “broken” Interface Builder UITableViewCell constraint in code and replacing it with one on the contentView.

In the end I used Adrian’s answer from the Stack Overflow question – this is a fairly generic solution, which moves all the constraints from the wrong view to the right view. This works well, and you can make your own subclass of UITableViewCell with that solution built in, and just use that to base new cell classes on.

And if Apple ever fix Interface Builder, this “hack” shouldn’t cause any problems, as there won’t be any constraints in the wrong place to find, so the code will just stop doing anything. Seems pretty clean.