33

I'm defining custom UITableViewCells in a storyboard. I'm also using some of the built in standard style cells. I need to set up constraints so that my custom cells match with the platform defined ones (have their titles correctly aligned at the left).

I've noticed that the left alignment of cells changes between iOS versions and the device it's running on. It seems like the left alignment is the same as the default cell separatorInset.

Here is UITableViewCells separatorInset for a few devices and iOS versions:

  • iPad on 7 – 15 points.
  • iPad on 8 – 20 points.
  • iPhone on 7 – 15 points.
  • iPhone on 8 – 16 points.

Other devices (iPhone 6+, iPad Mini) could be different – I've not exhaustively checked.

How would you go about ensuring that the custom cells and built in cells have the same left alignment of their labels?

Is there a sensible way to obtain these inset defaults and use them in auto layout constraints that are set up in a storyboard? How about in code?

5 Answers 5

36

I was having the same issue but the other answer couldn't help me as I was using static cells in UITableViewController. After a few trial-and-errors, I finally found a way to solve the separatorInset issue on iPhone 6+ without a single line of code.

enter image description here

I simply align the left edge of the UILabel with value of 0 [Content View (current distance = 0)] from the left margin. And also change the UILabel's X position to get 0. (For my case, in Interface Builder, margin was 7, UILabel's X = 8). The alignment works well on iPhone 4S, 5S, 6 and 6+.

EDIT: This changed in XCode 7. Additional step: Set "Preserve Superview Margins" of the respective cell's TableViewCell and its contentView to TRUE or check it in IB -> Size Inspector. Refer to @tebs1200's answer.

Hope this helps.

7
  • Thanks – I've come back to this just in the last few days, so I'll check this out.
    – Benjohn
    Commented Jul 25, 2015 at 18:33
  • THIS is the only correct answer. So simple. Thanks! Commented Sep 17, 2015 at 10:20
  • 1
    This worked for me until I put my UITableView in a child controller that was not flush with the left side of screen. In that case, the custom cell's margin is too small. I'll comment again if I can find an answer.
    – Rob N
    Commented Dec 21, 2015 at 19:55
  • "Preserve Superview Margins" is a great tip. If you don't check this it just uses a standard margin of 8px
    – Paludis
    Commented May 11, 2016 at 6:33
  • What if the UILabel is in the UITableView's header view (where there is no cell)? How can we let the UILabel respect superview then?
    – bunkerdive
    Commented Mar 27, 2017 at 17:43
31

You can implement the solution suggested by Mark purely in the storyboard:

  1. Make sure the custom cell is selected.

    Table View Cell selected in view tree

  2. Make sure Preserve Superview Margins is selected in the Size inspector

    'Preserve Superview Margins' selected in the Size inspector

  3. Now select the cell's Content View

    enter image description here

  4. Make sure Preserve Superview Margins is selected here too (see image in step 2.)

  5. Select the label (or other view) in your custom prototype cell.
  6. Constrain it's left edge 0 pixels from the margin.

    enter image description here

7

What worked for me was adding these 2 lines to my custom UITableViewCell implementation:

self.preservesSuperviewLayoutMargins = YES;
self.contentView.preservesSuperviewLayoutMargins = YES;
// ... add test view to content view...

Then I used Auto Layout with the default spacing:

[self.contentView addConstraints:[NSLayoutConstraint 
  constraintsWithVisualFormat:@"H:|-[testView]-|" options:0 metrics:nil 
   views:@{@"testView":testLabel}]];

[self.contentView addConstraints:[NSLayoutConstraint 
  constraintsWithVisualFormat:@"V:|-[testView]-|" options:0 metrics:nil 
   views:@{@"testView":testLabel}]];
3
  • Thanks – I've come back to this just in the last few days, so I'll check this out.
    – Benjohn
    Commented Jul 25, 2015 at 18:33
  • This is what I needed! Although I set the preservesSuperviewLayoutMargins property in the size inspector.
    – dontangg
    Commented Sep 18, 2015 at 19:51
  • To make it perfectly aligned, I've also set preservesSuperviewLayoutMargins = YES for the table view. Commented Sep 21, 2017 at 10:36
2

In iOS8 Apple introduced layoutMargins

You can set it in your storyboard or on your code simply like this :

cell.layoutMargins = UIEdgeInsetsZero // change by your custom value

Before that, you must set preservesSuperviewLayoutMargins to NO to prevent the cell from inheriting the Table View's margin settings

preservesSuperviewLayoutMargins : A Boolean value indicating whether the current view also respects the margins of its superview.

Hope this can help you ;)

0
0

This is years later and I didn't have any luck with the solutions above. I found that setting the leading constraint (in the storyboard) to 16 generally and 20 for height size class .compact works well for iOS 13 on various devices. However, for older iOS versions I ended up wiring that constraint to the custom cell's class and adding this:

    @IBOutlet var stackViewLeadingConstraint: NSLayoutConstraint!


    override func layoutSubviews() {
        super.layoutSubviews()
        guard #available(iOS 13, *)
            else {
                if traitCollection.verticalSizeClass == .compact {
                    stackViewLeadingConstraint.constant = 16
                }
                return
        }
    }

UPDATE: I got nervous about how fragile this approach might be. For my current situation I realized I can use a variety of system tableView cells to satisfy the requirements without mixing in custom cells. That seems to solve the alignment issues.

Not the answer you're looking for? Browse other questions tagged or ask your own question.