在一个表视图中有许多不同的uitableviewcell

时间:2022-10-21 23:41:11

I have an NSDictionary that we will say is like this:

我有一个NSDictionary我们会说

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.

等等。现在我要做的是创建一个表视图,它显示所有这些信息,但是基于dictionary键是什么,使用不同类型的单元格。例如,电影使用cellforfilms书籍使用cellForBooks音乐使用cellForMusic,每个都有自己的布局。

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).

等等……你能给我指出什么想法或资源吗?我只关心iOS 5支持(故事板)。

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:

最终的工作是将数据的结构更改为一个字典数组,然后添加一个键:类型值:book/movie/music到每个条目。现在的数据结构是:

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:

每一个都在故事板中有一个不同的tableviewcell。我们发现如果你想使用任何内置的单元格特性,比如cell. textlabel。你需要这样做的文字:

cell.textLabel.text = [object objectForKey:@"name"];
cell.textLabel.backgroundColor = [UIColor clearColor]; 
cell.textLabel.opaque = NO;

Hope this helps someone else in the future.

希望这能帮助未来的其他人。

5 个解决方案

#1


6  

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方法中,您可以根据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;
}

#2


6  

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:

最终的工作是将数据的结构更改为一个字典数组,然后添加一个键:类型值:book/movie/music到每个条目。现在的数据结构是:

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:

每一个都在故事板中有一个不同的tableviewcell。我们发现如果你想使用任何内置的单元格特性,比如cell. textlabel。你需要这样做的文字:

cell.textLabel.text = [object objectForKey:@"name"];
cell.textLabel.backgroundColor = [UIColor clearColor]; 
cell.textLabel.opaque = NO;

Hope this helps someone else in the future.

希望这能帮助未来的其他人。

#3


3  

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).

在故事板中,设置tableView来使用动态原型。然后,为要使用的每一种单元格创建一个单元格。适当地定制它们,然后在检查器(例如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:

然后,在tableview:cellForRowAtIndexPath:方法中,为索引路径上的内容确定合适的单元格类型。如果indexPath上的单元格应该是一个movie单元格,您将使用:

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:

这将为您提供您在故事板中指定为“MovieCell”的单元格。如果需要进一步定制它,可以创建一个UITableViewCell子类,并为故事板中的单元格指定它。然后,您可以参考这里的属性等,通过转换返回的单元格来进行定制:

MovieTableViewCell *movieCell = (MovieTableViewCell *)cell;
// customize

#4


0  

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.

我的意见是您应该在一个单元中实现所有的单元类型。这意味着您应该有一个UITableViewCell类和所有的。xib类。然后在cellForRowAtIndexPath中,创建单元格,然后根据实际需求显示/隐藏构成书籍或电影的子视图。

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]).

在这种设计中,您的单元格将是重量级的。但是,它仍然比使用几个单元格类要好,因为这种方式可以更有效地重用单元格([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.

我相信UITableView是针对一种细胞设计的。因此,如果布局不同,仍然可以将它们放在一个地方,并使用框架或显示/隐藏来控制单元格行为。

#5


0  

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;
}

#1


6  

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方法中,您可以根据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;
}

#2


6  

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:

最终的工作是将数据的结构更改为一个字典数组,然后添加一个键:类型值:book/movie/music到每个条目。现在的数据结构是:

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:

每一个都在故事板中有一个不同的tableviewcell。我们发现如果你想使用任何内置的单元格特性,比如cell. textlabel。你需要这样做的文字:

cell.textLabel.text = [object objectForKey:@"name"];
cell.textLabel.backgroundColor = [UIColor clearColor]; 
cell.textLabel.opaque = NO;

Hope this helps someone else in the future.

希望这能帮助未来的其他人。

#3


3  

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).

在故事板中,设置tableView来使用动态原型。然后,为要使用的每一种单元格创建一个单元格。适当地定制它们,然后在检查器(例如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:

然后,在tableview:cellForRowAtIndexPath:方法中,为索引路径上的内容确定合适的单元格类型。如果indexPath上的单元格应该是一个movie单元格,您将使用:

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:

这将为您提供您在故事板中指定为“MovieCell”的单元格。如果需要进一步定制它,可以创建一个UITableViewCell子类,并为故事板中的单元格指定它。然后,您可以参考这里的属性等,通过转换返回的单元格来进行定制:

MovieTableViewCell *movieCell = (MovieTableViewCell *)cell;
// customize

#4


0  

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.

我的意见是您应该在一个单元中实现所有的单元类型。这意味着您应该有一个UITableViewCell类和所有的。xib类。然后在cellForRowAtIndexPath中,创建单元格,然后根据实际需求显示/隐藏构成书籍或电影的子视图。

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]).

在这种设计中,您的单元格将是重量级的。但是,它仍然比使用几个单元格类要好,因为这种方式可以更有效地重用单元格([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.

我相信UITableView是针对一种细胞设计的。因此,如果布局不同,仍然可以将它们放在一个地方,并使用框架或显示/隐藏来控制单元格行为。

#5


0  

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;
}