Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 490
starwars25 Avatar asked Aug 13 '15 13:08

starwars25


1 Answers

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.

like image 109
Rob Avatar answered Nov 01 '22 02:11

Rob