UITableView:处理混合单元格表格中的单元格select查看静态和dynamic单元格

我想在组合的表格视图中混合dynamic和静态单元格:我想在静态单元格的顶部有两个部分,后面跟着一部分dynamic单元格 (请参阅下面的屏幕截图)。 我已经将表格视图内容设置为静态单元格

混合动态和静态表格视图单元格

编辑

基于AppleFreak的build议,我改变了我的代码如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell; if (indexPath.section <= 1) { // section <= 1 indicates static cells cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; } else { // section > 1 indicates dynamic cells CellIdentifier = [NSString stringWithFormat:@"section%idynamic",indexPath.section]; cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; } return cell; } 

但是,我的应用程序崩溃与错误信息

终止应用程序由于未捕获的exception“NSInternalInconsistencyException”,原因:'UITableView数据源必须从tableView:cellForRowAtIndexPath:'返回一个单元格

对于第0行和第0行。对于第0行和第0行,从cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]格返回的cell = [super tableView:tableView cellForRowAtIndexPath:indexPath] nil

我的代码有什么问题? 我的店可能有问题吗? 我没有设置任何网点,因为我是UITableViewController子类,并且应该没有设置tableview的任何网点(?)。 任何build议如何更好地做到这一点?

在这里输入图像说明

编辑二

我已经在故事板中重新创build了我的场景(请参阅上面我更新的屏幕截图),并重写了视图控制器以便从新的基础开始。 我也读过苹果论坛的描述,因为applefreakbuild议。 然而,我运行在第一个问题的方法numberOfSectionsInTableView:tableView ,其中我增加了一个静态部分(两个)的数量。

  - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return [super numberOfSectionsInTableView:tableView] + 1 ; } 

该应用程序崩溃与错误消息:

由于未捕获的exception'NSRangeException',原因:'*** – [__ NSArrayI objectAtIndex:]:index 2 beyond bounds [0..1]'

为什么这个代码不适合我,即使我遵循了苹果和applefreak的build议? 有可能在iOS 6中tableView有所改变?

解决scheme :我现在在下面的答案中使用了AppleFreaks代码示例。 谢谢,AppleFreak!

编辑三:单元格select:

如何处理混合(dynamic和静态单元格)单元格表格视图中的单元格select ? 我什么时候打super电话,什么时候打电话给self tableView ? 当我使用

 [[super tableView] selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone] 

并尝试检查所选的索引path:

 UITableView *tableView = [super tableView]; if ( [[tableView indexPathForSelectedRow] isEqual:customGrowthIndexPath] ) { .. } 

我得到的返回值nil

由于找不到我的错误来源,我真的很感谢你的帮助

对于静态单元,你需要调用超级方法。 我认为你将会扩展UITableViewController。 见下文

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell; /* Detect cell is static or dynamic(prototype) based on the index path and your settings */ if ("Cell is prototype") cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; else if ("Cell is static") cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; // Modify cell properties if you want return cell; } 

有关混合单元格的更多信息,请参阅在苹果论坛上混合静态和dynamic表格视图内容讨论。

[编辑]

如果您还没有阅读上面的苹果链接,请仔细阅读。 对于dynamic内容,您将首先使用代码中的给定标识符来构build单元格。 下一次在病房,你会出院的细胞,而不是build设! 这是旧的方式。

此外,请记住,静态数据源认为只有2个部分(例如)。 你不能问第二部分,因为它认为只有部分0和1.如果你打算在dynamic内容中插入dynamic内容,但是在表的最后,你需要在转发数据的时候撒谎源方法。 例如,您的numberOfRowsInSection:方法应该如下所示:

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (section == 1) { return 1; } else if (section > 1){ section--; // Basically you are forming sections for dynamic content } return [super tableView:tableView numberOfRowsInSection:section]; } 

关键是对dynamic内容进行调整,以便静态数据源仍然可以获得预期的值

[编辑]

这里是完整的工作示例并进行了testing。 只要复制代码中的以下所有方法,就可以直接使用。 混合单元格时,必须覆盖所有的tableview方法。 按照您的要求返回“numberOfSectionsInTableView”中静态和dynamic部分的总数,然后返回其余的每个方法; 如果所讨论的部分或行是静态的,只需调用super即可,如果它是dynamic的,就像在普通的UITableViewController子类中那样传回相关的细节。 在这个例子中,我只是返回零或硬编码的值。

欲了解更多信息,请在苹果论坛上查看此主题。

 - (int)numberOfSectionsInTableView:(UITableView *)tableView { return 3; } - (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { return nil; } - (NSString*)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { return nil; } - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { return NO; } - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { return NO; } -(float)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 44.0f; } - (float)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { return 44.0f; } - (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 44.0f; } - (UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { return nil; } -(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { return nil; } -(int)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath { return 5; } - (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if(section == 0) return 2; if(section == 1) return 2; return 5; } - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if(indexPath.section <= 1) return [super tableView:tableView cellForRowAtIndexPath:indexPath]; static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; cell.textLabel.text = @"dynamic row"; return cell; } 

[编辑]

您不要在didSelectRowAtIndexPath中调用super。 这很简单。 看下面的代码。

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { int row = indexPath.row; [tableView deselectRowAtIndexPath:indexPath animated:YES]; UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath]; //process the cell } 

使用静态单元自定义dynamic单元的最佳和最简单的方法:

1)将容器视图放置在dynamic表格视图的标题中2)将静态表格视图分配给该容器并取消“滚动已启用”

如果没有单元出队,那么单元将是零,因此你必须分配/初始化一个新单元。 请尝试退出一个单元格后检查单元格的值,并创build一个新的单元格,如果它是零。

谢谢applefreak的全面回答。 我将在这里添加我的build议,如果为静态部分添加虚拟部分,则不需要任何部分计算。 你甚至可以在那里添加占位符元素。 这样你就不必重新创buildNSIndexPath 。 一个重要的事情是重写每个使用NSIndexPath的方法,因为这会由于数组索引不匹配而导致应用程序崩溃。

另外,我完全放弃了使用出列机制,静态地创build了单元格,因为我没有那么多的单元格。 这使得tableView:cellForRowAtIndexPath:非常简单。

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == 0) { return _locationCells[indexPath.row]; } else { return [super tableView:tableView cellForRowAtIndexPath:indexPath]; } } 

只要记住占位符部分。

 UITableViewCell *cell = [self dequeueReusableCellWithIdentifier:@"cellIdentify"]; if (cell == nil) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellIdentify"]; 

只要你不拨打分配。 如果你不想重用,只是不要调用dequeueReusableCellWithIdentifier。