8

I have subclassed UITableViewCell to create a custom cell with a button and 2 labels. The cell definition is loaded from a xib using the pattern outlined in Dave Mark's Beginning iPhone Development. Here's the essential code:

    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MarketItemCustomCell" owner:self options:nil];

    for (id oneObject in nib)
    {
        if ([oneObject isKindOfClass:[MarketItemCustomCell class]])
        {
            cell = (MarketItemCustomCell *)oneObject;
            break;
        }
    }

The labels and button display as expected but the indentation level is not respected. I have implemented indentationLevelForRowAtIndexPath like below, but the cell is still aligned all the way to the left.

- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        <snip/>
        return 5;
    }

Note that the indentation level works fine when I'm not using a custom cell.

Any hints?

Daniel
  • 8,794
  • 4
  • 48
  • 71

3 Answers3

21

Update for iOS 8: The code below no longer works for some reason

Alternate suggestion for iOS 8:

Consider creating an AutoLayout constraint to represent the indenting left margin

At runtime, modify this constraint to change the indent level

If you have a custom UITableViewCell subclass, this subclass can have an IBOutlet mapped to the constraint. (Unfortunately Apple did not provide a findConstraintByTag/Id function)

The ironically named "constant" property of the NSLayoutConstraint can be modified to change the indent level.

For iOS 7, this works (but should no longer be recommended)

Based on vodkhang's suggestion, I implemented the following solution in my UITableViewCell sublass. Not sure if this is the best solution but it appears to work fine.

- (void)layoutSubviews
{
    [super layoutSubviews];

    float indentPoints = self.indentationLevel * self.indentationWidth;

    self.contentView.frame = CGRectMake(indentPoints,
                                          self.contentView.frame.origin.y,
                                          self.contentView.frame.size.width - indentPoints, 
                                          self.contentView.frame.size.height);
}
Daniel
  • 8,794
  • 4
  • 48
  • 71
  • 1
    This is terrific for indenting the content view - thanks! How about indenting the cell itself? I thought I'd remove contentView from the above and look to see if indentationLevel is not 0, but that looks icky. – Joe D'Andrea Jun 26 '12 at 15:17
  • how does one modify a NSLayoutConstraint? – Gerry Sep 03 '14 at 20:13
  • 1
    The ironically named "constant" property of the NSLayoutConstraint can be modified to change the indent level – Daniel Sep 03 '14 at 23:42
  • 2
    Expanding on Daniels answer, the constraint system worked by doing the following: In your UITableViewDelegate's indentationLevelForRowAtIndexPath method, set the correct indentation level, then in you UITableViewCell subclass's layoutSubviews method increase the constraint's constant by self.indentationLevel * self.indentationWidth; – Fraser Oct 09 '14 at 04:03
  • Great, Working perfect!! – Nikunj Oct 18 '14 at 07:20
  • 1
    Didn't realize you could map an IBOutlet to a constraint. Really nice solution, indeed. – Tapani May 21 '15 at 18:35
1

I think that you need to customize the indentation level in your custom UITableViewCell. I guess this method (and methods like – tableView:heightForRowAtIndexPath:) will not affect in the case of UITableViewCell if your custom UITableViewCell already specified it

vodkhang
  • 18,639
  • 11
  • 76
  • 110
0

If you design a UITableViewCell in a xib, you'll be using the customView cell property, which does not utilize indentation automatically. You can subclass UITableViewCell and implement layoutSubviews to change your frame based on indentation or you can do the same from wherever you configure your cells in your table delegate or datasource. I wish that Apple implemented indentation for custom cells.

Peter DeWeese
  • 18,141
  • 8
  • 79
  • 101