Reputation: 405
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
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
Reputation: 437592
There are two approaches:
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.
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
Reputation: 2220
Try this in your cellForRowAtIndexPath method
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
Hope it helps.
Upvotes: 0