UITableView:处理混合单元格表中的单元格选择静态和动态单元格 [英] UITableView: Handle cell selection in a mixed cell table view static and dynamic cells

查看:136
本文介绍了UITableView:处理混合单元格表中的单元格选择静态和动态单元格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在分组表视图中混合动态和静态单元格:我希望在顶部获得两个带有静态单元格的部分,然后是部分的动态单元格(请参阅下面的屏幕截图)。我已将表格视图内容设置为静态单元格

I am trying to mix dynamic and static cells in a grouped table view: I would like to get two sections with static cells at the top followed by a section of dynamic cells (please refer to the screenshot below). I have set the table view contents to static cells.

基于AppleFreak的建议我更改了我的代码如下:

Based on AppleFreak's advice I have changed my code as follows:

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

}

但是,我的应用程序崩溃并显示错误消息

However, my app crashes with error message


由于未捕获异常而终止应用
'NSInternalInconsistencyException',原因:'UITableView dataSource
必须从tableView返回一个单元格:cellForRowAtIndexPath: '

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'

第0部分和第0行。从返回的单元格= [super tableView:tableView cellForRowAtIndexPath: indexPath] 第0部分,第0行是 nil

for section 0 and row 0. The cell returned from cell = [super tableView:tableView cellForRowAtIndexPath:indexPath] for section 0 and row 0 is nil.

有什么问题我的代码?我的网点可能有问题吗?我没有设置任何出口因为我是 UITableViewController 的子类,并且据说没有设置tableview的任何出口(?)。关于如何做得更好的建议?

What is wrong with my code? Could there be any problems with my outlets? I haven't set any outlets because I am subclassing UITableViewController and supposedly do not any outlets for tableview to be set (?). Any suggestions on how to better do it?

我在故事板中重新创建了我的场景(请参阅我更新的屏幕在上面拍摄)并重写视图控制器以便从新基础开始。我也在Apple的论坛中阅读了applefreak建议的描述。但是,我使用方法 numberOfSectionsInTableView:tableView 运行我的第一个问题,其中我将静态部分(两个)的数量增加一个。

I have recreated my scene in storyboard (please refer to my updated screen shot above) and rewritten the view controller in order to start from a new base. I have also read the description in Apple's forum as applefreak suggested. However, I run in my first problem with the method numberOfSectionsInTableView:tableView, in which I increment the number of static sections (two) by one.

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

该应用程序崩溃并显示错误消息:

The app crashed with the error message:


由于未捕获的异常'NSRangeException'而终止应用程序,原因:
'*** - [__ NSArrayI objectAtIndex:]:索引2超出边界[0 .. 1]'

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 1]'

为什么这段代码对我不起作用,即使我遵循Apple和applefreak建议?在iOS 6中,tableView有可能发生了一些变化吗?

Why is this code not working for me even though I followed Apple's and applefreak recommendations? It is possible that the tableView has changed a bit in iOS 6?

解决方案:我现在使用AppleFreaks代码示例了解它回答如下。谢谢,AppleFreak!

Solution: I got this to work now using AppleFreaks code sample in his answer below. Thank you, AppleFreak!

如何处理单元格选择在混合(动态和静态单元格)单元格表视图中?
我何时拨打 super ,何时拨打 self tableView
当我使用

How can I handle cell selection in a mixed (dynamic and static cells) cell table view? When do I call super and when do I call self tableView? When I use

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

并尝试检查所选的索引路径:

and try to check for the selected index paths with:

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

I获得 nil 的返回值。

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

As I can't find the source of my error, I really would appreciate your help

推荐答案

对于静态单元格,您需要调用super方法。我假设您将扩展UITableViewController。见下文

For static cells you need to call super method. I presume that you will be extending UITableViewController. See below

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

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

Also for more information on mixing cells see Mixing static and dynamic table view content discussion on apple forums.

如果您还没有阅读上面的苹果链接,请仔细阅读。对于动态内容,您将首次使用代码本身中的给定标识符构建单元格。下次在病房里,你会将细胞出列而不是建造它!这是旧的方式。

If you haven't read apple link above then please do so carefully. For dynamic content you will build the cell first time with the given identifier in the code itself. Next time on wards you will dequeue the cell rather than building it! It's the same old way.

此外,请记住静态数据源认为只有2个部分(例如)。你不能问第2部分,因为它认为只有第0和第1部分。如果你要在表格末尾的任何地方插入动态内容,你需要在转发数据时欺骗超级源方法。例如,您的numberOfRowsInSection:方法应如下所示:

Moreover, remember that the static data source thinks there are only 2 sections(for example). You can't ask it about section 2, because it thinks there are only sections 0 and 1. If you're going to be inserting dynamic content anywhere but the end of the table, you need to lie to super when you forward the data source methods. Your numberOfRowsInSection: method, for example, should look something like this:

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

关键是调整动态内容以便静态数据源仍然得到它期望的值

The key is making the adjustment for your dynamic content so that the static data source still gets the values it expects

这是完整的工作示例并经过测试。只需复制代码中的所有以下方法,它应该直接工作。当您有混合单元格时,必须覆盖所有tableview方法。根据您的要求,返回numberOfSectionsInTableView中的静态和动态部分的总数,然后在每个剩余的方法中;如果有问题的部分或行是静态的,只需调用super,如果它是动态的,就像在普通的UITableViewController子类中一样传回相关的细节。在这个例子中,我只是返回nil或硬编码值。

Here is the complete working example and tested. Just copy past all of following methods in your code and it should work straight way. You have to override all the tableview methods when you have mixed cells. Return the total number of static and dynamic sections in "numberOfSectionsInTableView" as per your requirements, and then in each of the remaining methods; if the section or row in question is static just call through to super, if it's dynamic pass back the relevant details as you would in a normal UITableViewController subclass. In this example, I am simply returning nil or hard coded values.

有关更多信息,请查看这个主题在苹果论坛上。

For more information check this thread on apple forums.

- (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。这是直截了当的。请参阅下面的代码。

You don't call super in didSelectRowAtIndexPath. It's straight forward. See below code.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
     int row = indexPath.row;
     [tableView deselectRowAtIndexPath:indexPath animated:YES];

     UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
     //process the cell
}

这篇关于UITableView:处理混合单元格表中的单元格选择静态和动态单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆