62

If I create a UITableViewController, for example via File → New Project... → iOS → Master-Detail Application in Xcode, a UITableView is created with a prototype cell.

The generated view hierarchy is:

UITableViewController view hierarchy

A left "margin" is automagically created between the Cell's Content UIView left edge and the "Title" text's UILabel element as shown below in orange.

Prototype cell gap

This results in a corresponding margin between the device's screen edge and the UILabel text at runtime:

Runtime gap

So, where is the width of this gap set, and how can it be adjusted?

The controls in the Size Inspector for the UILabel are greyed out:

enter image description here

My preferred option would to be able to set the width of this gap from within Interface Builder, but I would also like to understand where this gap is being set, and how to alter it programmatically.

j b
  • 5,147
  • 5
  • 41
  • 60

10 Answers10

57

You just need to set contentInset property of the table view. You can set value according to your need.

self.tableView.contentInset = UIEdgeInsetsMake(0, -15, 0, 0);

OUTPUT RESULT

brandonscript
  • 68,675
  • 32
  • 163
  • 220
MilanPanchal
  • 2,943
  • 1
  • 19
  • 37
  • This works, thanks! Do you know if it is possible to set the `contentInset` in Interface Builder? – j b Oct 01 '14 at 08:28
  • 1
    @JamieBullock... Yes its possible even using Interface Builder. For that select your TableView in IB > Select Identity Inspector (Right side - 3rd option) > Add entry like following in User Defined Runtime Attributes by clicking plus(+) icon. [Detials: Keypath:contentInset, Type:Rect, Value: {{0, -15}, {0, 0}} ] – MilanPanchal Oct 02 '14 at 05:58
  • 35
    I don't think this is a good solution, if you do that, it makes your UITableViewCell move to left with 15, and cell's right has 15 margin. – Meilbn Mar 13 '16 at 03:51
  • 1
    can i give different marines to different cell? not one for all – H Raval Dec 15 '16 at 05:29
  • 2
    this will make content move left 15pt ,and will left 15pt space on the right side in iOS13 – leonardosccd Feb 13 '20 at 13:09
48

Go to Main.storyboard > select the UITableViewCell > Attributes Inspector. Change Separator dropdown list from Default Insets to Custom Insets. Change the left inset from 15 to 0

enter image description here

Amal T S
  • 3,327
  • 2
  • 24
  • 57
Farhan C K
  • 1,159
  • 18
  • 35
  • 2
    This is still the right way to do this within Xcode's interface builder, in 2019 with Xcode 10.x and iOS 12. – Mason Jan 28 '19 at 06:41
43

Starting from iOS 8 is available the cell property layoutMargins. So the correct way to adjust cell margins is setting this property in your tableView:cellForRowAtIndexPath or in your custom UITableViewCell in this way:

override func awakeFromNib() {
    super.awakeFromNib()

    self.layoutMargins = UIEdgeInsetsZero //or UIEdgeInsetsMake(top, left, bottom, right)
    self.separatorInset = UIEdgeInsetsZero //if you also want to adjust separatorInset
}

I hope this can help someone.

Francesco Vadicamo
  • 5,522
  • 35
  • 29
  • 3
    I'd like to suggest that `self.contentView.layoutMargins = UIEdgeInsetsZero` will have the intended effect. At least for me since I align all views relative the content view margins. – Andreas Mar 09 '16 at 17:18
  • 1
    I actually added these values to the UITableView itself, rather than the cells, and it worked fine (with iOS 9.2) – Mike Gledhill May 25 '16 at 09:57
  • 1
    i want to give different margins for different cell so can you please suggest me how can i do this – H Raval Dec 15 '16 at 05:38
  • 1
    Starting with iOS 11 `directionalLayoutMargins` should be used instead, as per [layoutMargins doc](https://developer.apple.com/documentation/uikit/uiview/1622566-layoutmargins) – Gobe Mar 08 '19 at 20:12
10

Just add the method in your code as mentioned in the below link

How do I eliminate the margin on the left side of a UITableView, without creating a gap on the right?

The method is like this in Objective-C:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
    if ([tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [tableView setSeparatorInset:UIEdgeInsetsZero];
    }
    if ([tableView respondsToSelector:@selector(setLayoutMargins:)]) {
    [tableView setLayoutMargins:UIEdgeInsetsZero];
    }
    if ([tableView respondsToSelector:@selector(setLayoutMargins:)]) {
    cell.preservesSuperviewLayoutMargins = NO;
    [cell setLayoutMargins:UIEdgeInsetsZero];
    }
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]){
    [cell setSeparatorInset:UIEdgeInsetsZero];
    }
}

Swift 3 and 4

public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        cell.separatorInset = .zero
    }
    if (cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins))) {
        cell.preservesSuperviewLayoutMargins = false
    }

    if (cell.responds(to: #selector(setter: UIView.layoutMargins))) {
        cell.layoutMargins = UIEdgeInsets.zero
    }
    if tableView.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        tableView.separatorInset = .zero
    }
    
}
Alex Zavatone
  • 4,106
  • 36
  • 54
Chetan
  • 881
  • 14
  • 22
9

If you're using a xib for your cell, be sure that the "Relative to margin" is unchecked. You can check this via the inspector as shown in the following screenshot:

enter image description here

Alessandro Francucci
  • 1,528
  • 17
  • 25
6

In the TableView "Attributes inspector" set the Separator Insets to "Custom" with Left = 0. That is all you have to do!

Nicolai Nita
  • 173
  • 9
  • 6
    This changes the *separator* inset (used e.g. for table group titles), but doesn't affect the cell content. Setting Separator Insets -> Left to 0, doesn't affect the space between the cell's content view left edge and the UILabel. – j b Oct 01 '14 at 08:23
  • You are right! Howerver, you will need to use in your case a "custom style cell" with the table view separator insets with left = 0. You can notice on the right side of the milanpanchal's screenshot that the separators and disclosure indicators are shifted to left by 15px. – Nicolai Nita Oct 01 '14 at 09:01
  • 1
    "custom style cell" - will let you position the label on the desired position, the table view separator insets with left = 0 - will adjust the separator position. – Nicolai Nita Oct 01 '14 at 09:09
  • Thanks for the info. In practice I am already using a Custom cell for my project. The motivation for my question was to understand how the Basic cell layout was working, and @milanpanchal's answer illustrates this by showing that the margin comes from the `UITableView`'s `contentInset` property. – j b Oct 01 '14 at 09:37
5

As WTIFS mentioned, UITableViewCell's indentation property is a great way to indent text labels in a built-in cell styles. Just do something like this to achieve nice left margin:

cell.indentationLevel = 2;

This, however, would not work for imageView.

Dannie P
  • 4,464
  • 3
  • 29
  • 48
  • This archives an indentation level on the text label of the cell, not the entire cell along with an optional image view. – Munib Nov 27 '16 at 07:57
  • @return0 unfortunately, that's true Adding a note for that – Dannie P Dec 23 '16 at 15:12
  • hey no worries. Best way I found out to do this was simply to make a custom UIViewCell. That is pretty much the easiest options and has far greater flexibility. – Munib Dec 23 '16 at 15:24
3

Here is the swift version of Chetan's answer:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        tableView.separatorInset = UIEdgeInsets.zero
        tableView.layoutMargins = UIEdgeInsets.zero
        cell.preservesSuperviewLayoutMargins = false
        cell.layoutMargins = UIEdgeInsets.zero
        cell.separatorInset = UIEdgeInsets.zero
}
Paul Lehn
  • 3,202
  • 1
  • 24
  • 29
1

And if you want to change just the left margin of the cell's textlabel only, then change the Horizontal Space Constraint 'Constant' to say 16 or 8 based on the padding you want.(This is in the nib file). If you cant get to the 'constant' Select the label, change the x coordinate in the FrameRectangle View, and then click on the constraint pin at the left) enter image description here

Naishta
  • 11,885
  • 4
  • 72
  • 54
0

I think I just came up with an easy solution. lol.

The top answer have some problem...it decrease the left gap, but resulting a right gap.

I used the constrains in Interface Builder.

First add a -15 left margin constrain to the Table View.

Then add some Indentation to the Table Cell to make the contents look better.


Here're some step-by-step pics:

Add the constraint. Remember to uncheck the "spacing to nearest neighbor".

Add the constraint. Remember to uncheck the "spacing to nearest neighbor".

The Table Cells will move left. But seems too close to margin.

After adding the constraint

So choose the Table Cell, and add some indentation in the right area.

add some indentation

WTIFS
  • 980
  • 8
  • 12