I am using a grouped UITableView
with static cells for an options screen/scene. Everything is done in Xcode 6.1 / iOS 8.1.x / Storyboard using Autolayout. Within the table groups there are mixed types of cells and there are two types that cause me problems:
- Cells with custom style and
- Cells with style "Right Detail"
On cell #1 I can set a constraint for the left margin between the label and the leading container. On cell #2 I cannot set any constraints in Interface Builder as far as I know. I have set the left margin on the label in cell #1 so it aligns with the label in cell #2. Everything looks fine on an iPhone, but if I show the same table on an iPad where the size of the table view's container is half the screen size, cell #2 gets more margin (dynamically?) while cell #1 maintains the absolute margin I set in the constraints. I also tried to change the left margin in cell #1 with the attribute "relative to margin" but to no avail.
iPhone:
iPad (with tableview width = 1/2 screen size)
So the question is: How do I set the constraints for the label in cell #1 so that it aligns like cell #2.
Here is also a link to a Xcode 6.1 sample project demonstrating the problem. Run on iPhone and iPad to see the difference:
https://dl.dropboxusercontent.com/u/5252156/Code/tableViewTest.zip
This question might be related to Layout static table cell for iPhone and iPad, but it might also differ for iOS 8 since everything is supposed to be adaptive now. That's why I decided to post this question anyway.
Best Answer
How to fix it
After fighting with the apple bug reporting team with many sample projects and screenshots and dissecting that answer, I've found that the solution to have your custom-style cells behave consistently regarding their margins and be just like the default UITableViewCells, you have to do the following (mostly based on Becky's answer, I've highlighted what's different and what made it work for me) :
Select your cell's content view in IB
Go to the Size Inspector
In the Layout Margins section, check Preserve Superview Margins (do not click the plus-sign)
(And here's the key) Do the same for the cell itself (the content view's parent if you will)
Setup your constraints as follows : Label.Leading = Superview.Leading Margin (with a constant of 0)
Now all your cells will have their label consistent with the default cells! This works for me in Xcode 7 and up and it includes the fix mentioned in the thread I referred to. IB and the simulator should now show properly aligned labels.
You could also do some of this programmatically, for example in the View Controller's class :
Or you could have it set up by calling UIAppearance once at startup (I only know Swift, sorry) :
How and why it works
As Ethan kindly pointed out, Apple's own documentation on UIView describes
preservesSuperviewLayoutMargins
as follows :Therefore, if you want your cell's content to align with the TableView's margins (it's great-grandparent if you will), you need to have your content's two ascendants, Content View and the Table Cell itself, preserve the margins of their own superview.
Why this isn't default behavior surprises me : I feel like most developers who don't want to customize everything would expect this "inheritance" by default.