starwars25
starwars25

Reputation: 405

Subtitle in dequeueReusableCellWithIdentifier

I have this code

UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
Song *song = [self.music objectAtIndex:indexPath.row];

cell.textLabel.text = song.title;
cell.detailTextLabel.text = song.artist;

return cell;

I don't use Interface Builder. How I can make this cell to have a subtitle? All I get is a standard cell.

Upvotes: 6

Views: 2066

Answers (3)

Dharmesh Dhorajiya
Dharmesh Dhorajiya

Reputation: 3984

Try this code :

UITableViewCell *cell= [self.tableView dequeueReusableCellWithIdentifier:@"Cell"];

if (cell==nil) {
  // Using this way you can set the subtitle 
  cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Cell"];
}

Song *song = [self.music objectAtIndex:indexPath.row];
cell.textLabel.text = song.title;
cell.detailTextLabel.text = song.artist;

return cell;

Upvotes: 0

Rob
Rob

Reputation: 437592

There are two approaches:

  1. The old style approach is to not register any class, NIB or cell prototype, call dequeueReusableCellWithIdentifier without forIndexPath:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
        if (!cell) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Cell"];
        }
    
        Song *song = self.music[indexPath.row];
        cell.textLabel.text = song.title;
        cell.detailTextLabel.text = song.artist;
    
        return cell;
    }
    

    As we discussed elsewhere, this assumes that you do not register a class for that reuse identifier.

  2. The alternative is to register your own class in viewDidLoad:

    [self.tableView registerClass:[MyCell class] forCellReuseIdentifier:@"Cell"];
    

    and then call dequeueReusableCellWithIdentifier with forIndexPath option, but lose the code that manually tests if it is nil (because it never will be nil):

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    
        Song *song = self.music[indexPath.row];
        cell.textLabel.text = song.title;
        cell.detailTextLabel.text = song.artist;
    
        NSLog(@"title=%@; artist=%@", song.title, song.artist); // for diagnostic reasons, make sure both are not nil
    
        return cell;
    }
    

    This obviously assumes that you've implemented a UITableViewCell subclass that includes the subtitle (note I'm overriding the style):

    @interface MyCell : UITableViewCell
    @end
    
    @implementation MyCell
    
    - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
        return [super initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
    }
    
    @end
    

Personally, I think designing a cell prototype (which automatically registers the reuse identifier and takes care of all of this other stuff) is much easier. Even the old technique of registering a NIB is easier than the above. But if you want to do it entirely programmatically, those are the two approaches.

Upvotes: 12

Pradumna Patil
Pradumna Patil

Reputation: 2220

Try this in your cellForRowAtIndexPath method

    cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];

Hope it helps.

Upvotes: 0

Related Questions