Tony Stark
Tony Stark

Reputation: 25518

issue customizing UITableViewCell

I'm using the following code to just make a single UILabel on my cell. (I know this example is contrived; I can't even get this to work much less my ultimate design goal.)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{   
    static NSString *CellIdentifier = @"Photo";

    UILabel *username;
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;

        username = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 120.0, 20.0)];
        username.tag = USERNAME_TAG;
        username.font = [UIFont systemFontOfSize:14.0];
        username.textAlignment = UITextAlignmentLeft;
        username.textColor = [UIColor blackColor];
        username.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
        [cell.contentView addSubview:username];
    } else {
        username = (UILabel *)[cell.contentView viewWithTag:USERNAME_TAG];
    }

    //NSDictionary *photos = [self.photos objectAtIndex:indexPath.row];
    username.text = @"Testing!";

    return cell;
}

I got this template code from here

However, when I run the code, there is no text label in the cell, but the accessory does show up.

Upvotes: 0

Views: 131

Answers (3)

lnafziger
lnafziger

Reputation: 25740

Apple changed the behavior of dequeueReusableCellWithIdentifier when they released 5.0.

In 5.0+ it is guaranteed to always return a copy of your cell (if it exists in your xib/storyboard), even if you haven't even loaded a cell yet. Prior to this, it would return a cell only if there was one that was ready to be recycled.

Because of this, some older code which assumes that you will receive nil unless you have already initialized it will break.

So, get rid of the identifier (or the entire cell) in your xib/storyboard or modify your logic so that it initializes it when needed (perhaps based on whether or not there is a view with the specified tag).

Upvotes: 0

Adam Shiemke
Adam Shiemke

Reputation: 3742

I find it much easier to use a custom xib for table cells that don't lend themselves easily to one of the normal types. The basic steps are: create a xib with your row, create an outlet property, then in your cellForRowAtIndexPath method, call loadNibNamed and assign it to a local variable (that you return), and set the outlet back to nil.

The secret is that loading a nib with a nil outlet causes the nil outlet to be init'd and inflated with the contents of the nib.

Described here (scroll to Loading Custom Table-View Cells From Nib Files): http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7

If you need a lot of user interaction, you are probably better off sub-classing UITableViewCell and supplying it with its own xib. If you have a lot of controls on a cell, you will end up using tags to determine the source of events, which gets messy with more than a few tags.

Upvotes: 1

bryanjclark
bryanjclark

Reputation: 6404

It looks like you're just trying to add a "standard" UILabel to the UITableViewCell.

Here's what you do: every UITableViewCell of the UITableViewCellStyleDefault has a property called textLabel. In your code, do the following:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{   
    static NSString *CellIdentifier = @"Photo";

    UILabel *username;
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
    }
    cell.textLabel.text = @"Testing!";

    return cell;
}

PS: Looks like you're trying to add an image at some point? There's a property for that as well. Take a look at the documentation for the imageView property.

Upvotes: 0

Related Questions