5

I have prepared a simple test project for my question at GitHub.

When using UITableViewCellStyleSubtitle type of cells (called Subtitle in Xcode Interface Builder) - for some reason the horizontal lines are not reaching the left side of the screen:

app screenshot

At the above screenshot you can see that the separator lines in "empty cells" are occupying the whole width just fine.

First I thought that the icons (size: 46 x 46 pixels) were not fitting into the cells and tried to increase the row height, but this does not help.

Also I have tried to set Custom Insets to Custom and there Left to 0 pixels (both for Table View and for MyCell), but there is still a gap on the left side:

Xcode screenshot

Here the source code of my TableViewController.m:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.items = [[NSMutableArray alloc] initWithArray:@[
        @{@"title": @"Title 1", @"subtitle": @"Sub Title 1", @"icon": @"signal4.png"},
        @{@"title": @"Title 2", @"subtitle": @"Sub Title 2", @"icon": @"signal1.png"},
        @{@"title": @"Title 3", @"subtitle": @"Sub Title 3", @"icon": @"signal2.png"},
        @{@"title": @"Title 4", @"subtitle": @"Sub Title 4", @"icon": @"signal3.png"}
    ]];
}

#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.items.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell" forIndexPath:indexPath];

    NSDictionary* item = [self.items objectAtIndex:indexPath.row];
    cell.textLabel.text = item[@"title"];
    cell.detailTextLabel.text = item[@"subtitle"];
    UIImage* icon = [UIImage imageNamed:item[@"icon"]];
    [cell.imageView setImage:icon];

    return cell;
}

UPDATE: The source code from this answer has helped me at the end: iOS 8 UITableView separator inset 0 not working

fixed screenshot

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Remove seperator inset
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
           [cell setSeparatorInset:UIEdgeInsetsZero];
    }

    // Prevent the cell from inheriting the Table View's margin settings
    if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
        [cell setPreservesSuperviewLayoutMargins:NO];
    }

    // Explictly set your cell's layout margins
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}

/*
-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    // Force your tableview margins (this may be a bad idea)
    if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [self.tableView setSeparatorInset:UIEdgeInsetsZero];
    }

    if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
        [self.tableView setLayoutMargins:UIEdgeInsetsZero];
    }
} 
*/
Community
  • 1
  • 1
Alexander Farber
  • 21,519
  • 75
  • 241
  • 416
  • 1
    in iOS 8 you have to add some code to do so. Check the answer – Ashish Kakkad May 11 '15 at 12:58
  • 1
    Alexander, long time no see! :) Can I persuade you not to do this? There are aesthetic reasons why there are insets and why the insets are changed when there is an image. – Léo Natan May 12 '15 at 09:45

1 Answers1

10

Add Table View Separator Insets to Zero. Not Just for Table View Cell.

enter image description here

Add this code in cellForRowAtIndexPath:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //....
    if ([[[UIDevice currentDevice]systemVersion]floatValue]>=8.0)
    {
        cell.layoutMargins = UIEdgeInsetsZero;
        cell.preservesSuperviewLayoutMargins = NO;
    }
}

Integration with your code :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell" forIndexPath:indexPath];

    if ([[[UIDevice currentDevice]systemVersion]floatValue]>=8.0)
    {
        cell.layoutMargins = UIEdgeInsetsZero;
        cell.preservesSuperviewLayoutMargins = NO;
    }

    NSDictionary* item = [self.items objectAtIndex:indexPath.row];
    cell.textLabel.text = item[@"title"];
    cell.detailTextLabel.text = item[@"subtitle"];
    UIImage* icon = [UIImage imageNamed:item[@"icon"]];
    [cell.imageView setImage:icon];

    return cell;
}

See the preview :

enter image description here

Ashish Kakkad
  • 23,586
  • 12
  • 103
  • 136
  • 1
    Ok, Then let wait for another answer @AlexanderFarber – Ashish Kakkad May 11 '15 at 13:42
  • 2
    Brilliant! It's a pity there is no Nobel Prize for working around stupid iOS behavior. Of course, this solution comes at a price: the developer may have other reasons for _not_ wanting to change the cell margins. But there are ways around that (add a subview with margins of its own). – matt May 11 '15 at 19:06
  • 2
    Just to be clear: there is no need to involve the table. In `cellForRowAtIndexPath:` set three things: (1) The cell's separator inset; (2) the cell's layout margins; (3) the cell's `preservesSuperviewLayoutMargins`. That will do it. – matt May 11 '15 at 19:10
  • @AshishKakkad Thanks for the answer. However, after doing this some spaces are again left. Is there any way to cover those as well? – A_G Nov 27 '16 at 04:12