Reputation: 4111
I have an NSDictionary
that we will say is like this:
key: value:
name Bookshelf
movies Array containing: (Movie 1, Movie 2, Movie 3)
books Array containing: (Book 1, Book 2, Book 3)
music Array containing: (Music 1, Music 2, Music 3)
And so on. Now what I'm trying to do is create a tableView that displays all this information, but with different types of cells based on what the dictionary key is. For example, movies use cellForMovies
books use cellForBooks
music use cellForMusic
, each has it's own layout.
Obviously, I am oversimplifying, but hopefully you understand what I'm trying to do.
I am able to accomplish this if I do sections and a different cell type for each section, but I don't want to do that. I want to be able to have a table like this, for example:
cellForBooks
cellForMovies
cellForMovies
cellForMusic
cellForBooks
and so on...Any ideas or resources you can point me to? I only care about iOS 5 support (storyboards).
Edit with solution:
A big thank you to everyone who helped, especially atticus who put the final piece together.
What ended up working was to change the structure of the data to be an array of dictionaries and then add a Key: type Value: book/movie/music
to each entry. The data structure now looks like:
Array[0]: Dictionary: [Key: type Value: book], [Key: name Value: Physics];
Array[1]: Dictionary: [Key: type Value: music], [Key: name Value: Rock];
Then to configure the cells I did this:
NSString *CellIdentifier = @"Cell";
NSDictionary *object = [self.listOfStuff objectAtIndex:indexPath.row];
if ([[object objectForKey:@"type"] isEqualToString:@"book"]){
CellIdentifier = @"BookCell";
}else if ([[object objectForKey:@"type"] isEqualToString:@"music"]){
CellIdentifier = @"MusicCell";
}else if ([[object objectForKey:@"type"] isEqualToString:@"movie"]){
CellIdentifier = @"MovieCell";
}
each of these had a different tableviewcell in the storyboard. We figured out if you want to use any of the built-in cell features, like cell.textLabel.text
you needed to do this:
cell.textLabel.text = [object objectForKey:@"name"];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.opaque = NO;
Hope this helps someone else in the future.
Upvotes: 5
Views: 9218
Reputation: 4111
A big thank you to everyone who helped, especially atticus who put the final piece together.
What ended up working was to change the structure of the data to be an array of dictionaries and then add a Key: type Value: book/movie/music
to each entry. The data structure now looks like:
Array[0]: Dictionary: [Key: type Value: book], [Key: name Value: Physics];
Array[1]: Dictionary: [Key: type Value: music], [Key: name Value: Rock];
Then to configure the cells I did this:
NSString *CellIdentifier = @"Cell";
NSDictionary *object = [self.listOfStuff objectAtIndex:indexPath.row];
if ([[object objectForKey:@"type"] isEqualToString:@"book"]){
CellIdentifier = @"BookCell";
}else if ([[object objectForKey:@"type"] isEqualToString:@"music"]){
CellIdentifier = @"MusicCell";
}else if ([[object objectForKey:@"type"] isEqualToString:@"movie"]){
CellIdentifier = @"MovieCell";
}
each of these had a different tableviewcell in the storyboard. We figured out if you want to use any of the built-in cell features, like cell.textLabel.text
you needed to do this:
cell.textLabel.text = [object objectForKey:@"name"];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.opaque = NO;
Hope this helps someone else in the future.
Upvotes: 5
Reputation: 548
i think u should use the following as your cell identifier.
- (UITableViewCell *)tableView:(UITableView *)tmpTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *cellIdentifier = [NSString stringWithFormat:@"Cell%d%d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tmpTableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (nil == cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
// do ur stuff here
}
return cell;
}
Upvotes: 0
Reputation: 960
In your storyboard, set your tableView to use Dynamic Prototypes. Then, create a cell for each kind of cell you're going to use. Customize those appropriately, and then give each one a unique Reuse Identifier in the inspector (e.g. MovieCell).
Then, in your tableview:cellForRowAtIndexPath: method, determine the appropriate kind of cell for the content at that index path. If the cell at indexPath should be a movie cell, you would create the cell using:
static NSString * MovieCellIdentifier = @"MovieCell"; // This must match the storyboard
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MovieCellIdentifier];
That will give you the cell you specified as "MovieCell" in your storyboard. If you need to customize it further, create a UITableViewCell subclass and specify that for the cell in Storyboard. Then, you can refer to the properties etc. here for customization by casting the returned cell:
MovieTableViewCell *movieCell = (MovieTableViewCell *)cell;
// customize
Upvotes: 3
Reputation: 5819
My opinion is that you should implement all your cell types in one cell. Which means you should have one UITableViewCell
class and .xib for all of them. Then in cellForRowAtIndexPath
, create the cell, then depending on the actual requirement, show/hide the subviews that makes up a book or a movie.
In such design, your cell will be somewhat heavyweight. However, it's still better than using several cell classes because this way cell reusing is more efficient ([UITableView dequeueReusableCellWithIdentifier]
).
I believe UITableView is designed towards one type of cell. So if your layout varies, you can still put them in one place and use frame or show/hide to control cell behavior.
Upvotes: 0
Reputation: 1587
In your - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
method you can return many types of cells according to indexPath
.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row > 5) { // Your conditions here to choose between Books and Movies
BookCell *cell = [tableView dequeueReusableCellWithIdentifier:@"bookCell"];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"bookCell"];
}
return cell;
} else {
MovieCell *cell = [tableView dequeueReusableCellWithIdentifier:@"movieCell"];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"movieCell"];
}
return cell;
}
return nil;
}
Upvotes: 6