Jeremy
Jeremy

Reputation: 883

Does a TableViewCell have to have its own class?

I have successfully used custom UITableViewCells using separate classes, but I keep thinking there is an easier way so I have tried the following. The table builds, but the cells are blank (so presumably my custom cell is not displaying correctly). Any ideas appreciated.

My files are:

@interface RemediesPopUp : UIViewController <UITableViewDataSource, UITableViewDelegate>{

    UITableView *remediesDataTable;
    UITableViewCell *remediesTableCell;  // ** custom cell declared here **

    NSArray *remediesArray;

}

The table controls are:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    remediesTableCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (remediesTableCell == nil) {
        remediesTableCell = [[[UITableViewCell alloc] init] autorelease];
    }

    // Configure the cell.

    return remediesTableCell;

}

I dragged a custom cell object into the XIB file pane (so I have the View and a separate custom cell displayed). I connected the custom cell to File Manager. To test, I pasted a couple of (static) labels onto the custom cell so I could see if it was loading.

The page and table loads just fine, but the cells are blank (white).

Any ideas?

Upvotes: 0

Views: 126

Answers (2)

Stuart
Stuart

Reputation: 37053

First off, make sure that your custom cell is a custom subclass (subclass of UITableViewCell) and has its own nib file (for example, don't integrate it with your table view controller).

In the nib, select the identity inspector and ensure that your cell's class is CustomCell (or whatever you called it). Also make sure that under the attributes inspector you set its Identifier to "CustomCellIdentifier" or similar.

In your table view data source, your tableView:cellForRowAtIndexPath method should contain code similar to this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CustomCellIdentifier = @"CustomCellIdentifier";    // Same as you set in your nib

    CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier];
    if (cell == nil) {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];

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

    // Customise the labels etc...

    return cell;
}

This ensures that your custom cell is loaded directly from its own nib, allowing you to visually lay out any views or labels. The text for these labels can then be set once the appropriate cell has been dequeued/created.

In your code, your 'custom' cell is just a plain UITableViewCell. To customise the cell using interface builder, you need to create your own custom subclass of this.

EDIT

For a custom cell that uses only a nib (and not a custom subclass), change the above code example to cast the cell to a plain UITableViewCell, i.e. change CustomCell to UITableViewCell. In Interface Builder assign each of your cell's custom views (labels etc) with a unique tag.

With that in place, the code should look something like this:

#define MyLabelTag  10    // These should match the tags
#define MyViewTag   11    // assigned in Interface Builder.


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CustomCellIdentifier = @"CustomCellIdentifier";    // Same as you set in your nib

    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier];
    if (cell == nil) {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];

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

    // Get references to the views / labels from the tags.
    UILabel *myLabel = (UILabel *)[cell viewWithTag:MyLabelTag];
    UIView *myView = (UIView *)[cell viewWithTag:MyViewTag];

    // Customise the views / labels...
    // ...

    return cell;
}

Upvotes: 1

Snowman
Snowman

Reputation: 32071

What I usually do is put a UIView inside the UITableViewCell, and then put all your labels and other UI stuff in that UIView. If this doesn't work, let me know. I might have another solution.

Upvotes: 0

Related Questions