7

I am programmatically creating a tableview in objective c. How can I make the cells static programmatically?

Thanks

jpo
  • 3,679
  • 17
  • 52
  • 100

5 Answers5

15

Making cells static programmatically doesn't really make sense. Static cells are basically only for Interface Builder and requires the entire TableView to be static. They allow you to drag UILables, UITextFields, UIImageViews, etc. right into cells and have it show up just how it looks in Xcode when the app is run.

However, your cells can be "static" programmatically by not using an outside data source and hardcoding everything, which is usually going to be kind of messy and generally a poor idea.

I suggest making a new UITableViewController with a .xib and customizing it from there if you want "static" cells. Otherwise, just hardcode all your values and it's basically the same thing, but is probably poor design if it can be avoided.

MikeS
  • 3,853
  • 6
  • 31
  • 50
  • 6
    I think it's perfectly acceptable to programmatically create as many static tableview cells as you want if you want to avoid using InterfaceBuilder. There are many valid reasons for wanting to minimize use of InterfacerBuilder. – MH175 Nov 24 '18 at 20:35
9

By using a distinct cell identifier for each one you will get it. You could use something like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = [NSString stringWithFormat:@"s%i-r%i", indexPath.section, indexPath.row];
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
        //you can customize your cell here because it will be used just for one row.
    }

    return cell;
}
Ricard Pérez del Campo
  • 2,307
  • 1
  • 17
  • 22
3

You could also do it the old fashioned and just create the cell the way you want depending on the NSIndexPath, this works with Static Cell TVC's and regular table views (don't forget to return the proper number of sections and rows in their datasource methods):

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    switch indexPath.row {
        case 0:
            // First cell, setup the way you want

        case 1:
            // Second cell, setup the way you want
    }

    // return the customized cell
    return cell;
}
Darius Miliauskas
  • 3,039
  • 4
  • 29
  • 48
LJ Wilson
  • 14,327
  • 5
  • 34
  • 57
1

I you want to create cells structure for example for a settings screen or something like that and you maybe need just to modify some cells content but not their number or sections structure you can overload method of your UITableViewController subclass like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *aCell = [super tableView:tableView cellForRowAtIndexPath:indexPath];

    // Configure the cell...
    if ([aCell.reuseIdentifier isEqualToString:@"someIdentifier"]){
        //some configuration block
    }

    else if ([aCell.reuseIdentifier isEqualToString:@"someOtherIdentifier"]) {
        //other configuration block
    }
    return aCell;
}

But you can make it in a better way with a little bit more code;

1) In the begining of your .m file add typedef:

typedef void(^IDPCellConfigurationBlock)(UITableViewCell *aCell);

2) add cellConfigurations property to your TablviewControllerSubclass extention:

@interface IPDSettingsTableViewController ()

@property (nonatomic, strong) NSDictionary *cellConfigurations;
@property (nonatomic) id dataModel;

@end

3) Modify your static cells of TableviewController subclass in storyboard or xib and add unique cellReuseIdentifier for each cell you want to modify programmatically

4) In your viewDidLoad method setup cellsConfiguration blocks:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self SetupCellsConfigurationBlocks];
}

- (void)SetupCellsConfigurationBlocks
{
    //Store configurations code for each cell reuse identifier
    NSMutableDictionary *cellsConfigurationBlocks = [NSMutableDictionary new];        


    //store cells configurations for a different cells identifiers
    cellsConfigurationBlocks[@"someCellIdentifier"] = ^(UITableViewCell *aCell){
        aCell.backgroundColor = [UIColor orangeColor];
    };

    cellsConfigurationBlocks[@"otherCellIdentifier"] = ^(UITableViewCell *aCell){
        aCell.imageView.image = [UIImage imageNamed:@"some image name"];
    };

    //use waek reference to self to avoid memory leaks
    __weak typeof (self) weakSelf = self;
    cellsConfigurationBlocks[@"nextCellIdentifier"] = ^(UITableViewCell *aCell){
        //You can even use your data model to configure cell
        aCell.textLabel.textColor = [[weakSelf.dataModel someProperty] isEqual:@YES] ? [UIColor purpleColor] : [UIColor yellowColor];
        aCell.textLabel.text      = [weakSelf.dataModel someOtherProperty];
    };
    weakSelf.cellConfigurations = [cellsConfigurationBlocks copy];
}

5) overload tableView:cellForRowAtIndexPath method like this:

#pragma mark - Table view data source

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *aCell = [super tableView:tableView cellForRowAtIndexPath:indexPath];

    // configure cell
    [self configureCell:aCell withConfigurationBlock:self.cellConfigurations[aCell.reuseIdentifier]];
    return aCell;
}

- (void)configureCell:(UITableViewCell *)aCell withConfigurationBlock:(IDPCellConfigurationBlock)configureCellBlock
{
    if (configureCellBlock){
        configureCellBlock(aCell);
    }
}
Nikolay Shubenkov
  • 2,988
  • 1
  • 26
  • 31
0

It is pretty common to want to build a simple table to use as a menu or form, but using the built in API with the datasource and delegate callbacks don't make it easy to write or maintain. You may need to dynamically add/remove/update some cells, so using Storyboards by itself won't work.

I put together MEDeclarativeTable to programmatically build small tables. It provides the datasource and delegate for UITableView. We end up with an API where we provide instances of sections and rows instead of implementing datasource and delegate methods.

Michael Enriquez
  • 2,480
  • 19
  • 13