didSelectRowAtIndexPath 一次选择多行

发布于 2024-11-08 18:04:01 字数 2630 浏览 0 评论 0原文

我有一个填充了 27 行的 UITableView。我正在尝试更改所选单元格的 accessoryType 。我在 didSelectRowAtIndexPath: 委托方法中执行此操作。

我面临的问题是,当选择一行并更改单元格的 accessoryType 时,该行的第十一行也会被修改。

我尝试打印 [indexPath row] 值,但它仅显示所选的行,而不显示另一行。

我真的对这些事情感到困惑;请帮帮我。

添加代码 cellForRowAtIndexPath 方法

UITableViewCell *cell;
if ([indexPath row] == 0) {
    cell = [tableView dequeueReusableCellWithIdentifier:@"acell"];
}
else {
    cell = [tableView dequeueReusableCellWithIdentifier:@"bcell"];
}

cell.selectionStyle = UITableViewCellSelectionStyleNone;

if (cell == nil && [indexPath row] != 0) {
    cell = [[[UITableViewCell alloc] initWithStyle:
             UITableViewCellStyleSubtitle reuseIdentifier:@"bcell"] autorelease];
}
else if(cell == nil && [indexPath row] == 0){
    cell = [[[UITableViewCell alloc] initWithStyle:
             UITableViewCellStyleSubtitle reuseIdentifier:@"acell"] autorelease];
}

if ([cell.contentView subviews]){
    for (UIView *subview in [cell.contentView subviews]) {
        [subview removeFromSuperview];
    }
}
if ([indexPath row] == 0) {
    cell.textLabel.text = @"Select All";
    cell.textLabel.font = [UIFont boldSystemFontOfSize:13.0f];
}
else {
    cell.textLabel.text = @"Some Text Here"
    cell.detailTextLabel.text = @"Another piece of text here"   
}
return cell;

我正在执行 %10 因为该行为在第 11 行后重复,因此尝试为每 11 行创建新对象。

我的 didSelectRowAtIndexPath 方法代码是

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
    if ([indexPath row] != 0) {
        NSIndexPath *tempIndex = [NSIndexPath indexPathForRow:0 inSection:0];
        UITableViewCell *tempCell = [tableView cellForRowAtIndexPath:tempIndex];
        tempCell.accessoryType = UITableViewCellAccessoryNone;
    }
    cell.accessoryType = UITableViewCellAccessoryNone;
}
else{
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
if ([indexPath row] == 0) {
    for (int i = 0; i < [dataSource count]; i++) {
        NSIndexPath *tempIndex = [NSIndexPath indexPathForRow:i+1 inSection:0];
        UITableViewCell *tempCell = [tableView cellForRowAtIndexPath:tempIndex];
        if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
            tempCell.accessoryType = UITableViewCellAccessoryCheckmark;
        }
        else{
            tempCell.accessoryType = UITableViewCellAccessoryNone;
        }
    }
}

请帮助我以多项选择或任何其他方式解决多项选择的问题。

提前致谢!!

I have a UITableView populated with 27 rows. I am trying to change the accessoryType of the selected cell. I do that in the didSelectRowAtIndexPath: delegate method.

The problem I am facing is that, when selecting a row and changing the accessoryType of the cell, the eleventh row from that row also gets modified.

I have tried printing the [indexPath row] value, but it's showing only the row that was selected and not another one.

I am really puzzled by such stuff; please help me out.

ADDED THE CODE cellForRowAtIndexPath method

UITableViewCell *cell;
if ([indexPath row] == 0) {
    cell = [tableView dequeueReusableCellWithIdentifier:@"acell"];
}
else {
    cell = [tableView dequeueReusableCellWithIdentifier:@"bcell"];
}

cell.selectionStyle = UITableViewCellSelectionStyleNone;

if (cell == nil && [indexPath row] != 0) {
    cell = [[[UITableViewCell alloc] initWithStyle:
             UITableViewCellStyleSubtitle reuseIdentifier:@"bcell"] autorelease];
}
else if(cell == nil && [indexPath row] == 0){
    cell = [[[UITableViewCell alloc] initWithStyle:
             UITableViewCellStyleSubtitle reuseIdentifier:@"acell"] autorelease];
}

if ([cell.contentView subviews]){
    for (UIView *subview in [cell.contentView subviews]) {
        [subview removeFromSuperview];
    }
}
if ([indexPath row] == 0) {
    cell.textLabel.text = @"Select All";
    cell.textLabel.font = [UIFont boldSystemFontOfSize:13.0f];
}
else {
    cell.textLabel.text = @"Some Text Here"
    cell.detailTextLabel.text = @"Another piece of text here"   
}
return cell;

I am doing %10 because the behaviour is repeating after 11th row, hence trying to create new object for every 11th row.

My didSelectRowAtIndexPath methos code is

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
    if ([indexPath row] != 0) {
        NSIndexPath *tempIndex = [NSIndexPath indexPathForRow:0 inSection:0];
        UITableViewCell *tempCell = [tableView cellForRowAtIndexPath:tempIndex];
        tempCell.accessoryType = UITableViewCellAccessoryNone;
    }
    cell.accessoryType = UITableViewCellAccessoryNone;
}
else{
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
if ([indexPath row] == 0) {
    for (int i = 0; i < [dataSource count]; i++) {
        NSIndexPath *tempIndex = [NSIndexPath indexPathForRow:i+1 inSection:0];
        UITableViewCell *tempCell = [tableView cellForRowAtIndexPath:tempIndex];
        if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
            tempCell.accessoryType = UITableViewCellAccessoryCheckmark;
        }
        else{
            tempCell.accessoryType = UITableViewCellAccessoryNone;
        }
    }
}

Please help me in multiple selection or anyother way to solve the problem of multiple selection.

Thanks in advance!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

漫雪独思 2024-11-15 18:04:02

这是一种方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];        
    }

    [cell.textLabel setText:[NSString stringWithFormat:@"Row %d", indexPath.row]];

    NSIndexPath* selection = [tableView indexPathForSelectedRow];
    if (selection && selection.row == indexPath.row) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark; 
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;  
    }

    // Configure the cell.
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}

记住表视图中的每个单元格实际上都是重复使用的同一个对象。如果您没有在每次调用 cellForRowAtIndexPath 时设置附件类型,则当新单元格滚动到屏幕上时,它们都将具有相同的附件。

多重选择

对于多重选择来说,情况有点复杂。

您的第一个选择:未记录的 API

请注意,这仅在表格处于编辑模式时才有效。将每个单元格的编辑样式设置为未记录的 UITableViewCellEditingStyleMultiSelect。完成此操作后,您可以通过 UITableView 的未记录成员获取表视图的选择:indexPathsForSelectedRows。这应该返回所选单元格的数组。

您可以通过将其放入标题中来公开此功能:

enum {
    UITableViewCellEditingStyleMultiSelect = 3,
};

@interface UITableView (undocumented)
- (NSArray *)indexPathsForSelectedRows;
@end

然后为每个单元格设置编辑样式,如下所示:

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewCellEditingStyleMultiSelect;
}

当表格处于编辑模式时,您将在单元格上看到多选控件。

要查看其他未记录的 API,您可以使用 nm 命令行实用程序,如下所示:

nm /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/UIKit.framework/UIKit

您的第二个选项:自己管理选择

让您的 UITableView 子类包含一个数组,该数组指示选择了哪些单元格。然后在 cellForRowAtIndexPath 中,使用该数组配置单元格的外观。您的 didSelectRowAtIndexPath 方法应该如下所示:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([tableView indexPathIsSelected:indexPath]) {
        [tableView removeIndexPathFromSelection:indexPath];
    } else {
        [tableView addIndexPathToSelection:indexPath];
    }
    // Update the cell's appearance somewhere here
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
}

这假设您在 UITableView 子类中创建了 indexPathIsSelected、removeIndexPathFromSelection 和 addIndexPathToSelection 方法。这些方法应该完全按照其名称的含义进行操作:添加、删除和检查数组中的索引路径。如果您选择此选项,则不需要 didDeselectRowAtIndexPath 实现。

Here's one way to do it:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];        
    }

    [cell.textLabel setText:[NSString stringWithFormat:@"Row %d", indexPath.row]];

    NSIndexPath* selection = [tableView indexPathForSelectedRow];
    if (selection && selection.row == indexPath.row) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark; 
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;  
    }

    // Configure the cell.
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}

Remember every cell in the table view is actually the same object being re-used. If you don't set the accessory type every time cellForRowAtIndexPath is called, when new cells scroll onto the screen they're going to all have the same accessory.

Multiple Select

For multiple selection it's a bit more complicated.

Your first option: Undocumented API

Note that this only works when the table's in editing mode. Set each cell's editing style to the undocumented UITableViewCellEditingStyleMultiSelect. Once you do that, you can get the table view's selection via an undocumented member of UITableView: indexPathsForSelectedRows. That should return an array of the selected cells.

You can expose this bit of functionality by putting this in a header:

enum {
    UITableViewCellEditingStyleMultiSelect = 3,
};

@interface UITableView (undocumented)
- (NSArray *)indexPathsForSelectedRows;
@end

Then set the editing style for each cell like so:

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewCellEditingStyleMultiSelect;
}

When the table is in editing mode you'll see the multi-select controls on your cells.

To look through other undocumented API, you can use the nm command line utility like this:

nm /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/UIKit.framework/UIKit

Your second option: Manage the selection yourself

Have your UITableView subclass contain an array that indicates which cells are selected. Then in cellForRowAtIndexPath, configure the cell's appearance using that array. Your didSelectRowAtIndexPath method should then look something like this:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([tableView indexPathIsSelected:indexPath]) {
        [tableView removeIndexPathFromSelection:indexPath];
    } else {
        [tableView addIndexPathToSelection:indexPath];
    }
    // Update the cell's appearance somewhere here
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
}

This assumes you create indexPathIsSelected, removeIndexPathFromSelection, and addIndexPathToSelection methods in your UITableView subclass. These methods should do exactly what their names imply: Add, remove, and check for index paths in an array. You wouldn't need a didDeselectRowAtIndexPath implementation if you go with this option.

温折酒 2024-11-15 18:04:02

记住表视图中的每个单元格实际上是重复使用的同一个对象。如果您没有在每次调用 cellForRowAtIndexPath 时都设置附件类型,则当新单元格滚动到屏幕上时,它们都将具有相同的附件。” - daxnitro

这就是我被抓住的地方。我设置了我的,以便在我的“cellForRowAtIndexPath”函数中,我只会更改已检查单元格数组中指定的附件,而我应该做的是更新表中所有单元格的附件

换句话说:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//normal set up

    //retrieve key
    NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
    id obj = [settings objectForKey:@yourKey];

    //if the array is not populated, keep standard format for all cells
    if (obj == nil){
        selectedStyles = [[NSMutableArray alloc] initWithObjects:nil];
        [cell setAccessoryType:UITableViewCellAccessoryNone];  //no check mark
        [cell textLabel].textColor = [[UIColor alloc] initWithRed:0.0/255 green:0.0/255 blue:0.0/255 alpha:1.0];  //keep black color

    }
    //else retrieve information from the array and update the cell's accessory
    else{
        //if the cell is in your array, add a checkbox
        [cell setAccessoryType:UITableViewCellAccessoryCheckmark];  //add check box
        [cell textLabel].textColor = [[UIColor alloc] initWithRed:50.0/255 green:79.0/255 blue:133.0/255 alpha:1.0];  //change color of text label
        //if the cell is not in your array, then keep standard format
        [cell setAccessoryType:UITableViewCellAccessoryNone];  //no check mark
        [cell textLabel].textColor = [[UIColor alloc] initWithRed:0.0/255 green:0.0/255 blue:0.0/255 alpha:1.0];  //keep black color

希望这有帮助!

Remember every cell in the table view is actually the same object being re-used. If you don't set the accessory type every time cellForRowAtIndexPath is called, when new cells scroll onto the screen they're going to all have the same accessory." - daxnitro

This is where I got caught. I had mine set up so that in my "cellForRowAtIndexPath" function, I would only change the accessory for those specified in my array of checked cells, when what I should have done was update the accessory for all cells in the table.

In other words:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//normal set up

    //retrieve key
    NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
    id obj = [settings objectForKey:@yourKey];

    //if the array is not populated, keep standard format for all cells
    if (obj == nil){
        selectedStyles = [[NSMutableArray alloc] initWithObjects:nil];
        [cell setAccessoryType:UITableViewCellAccessoryNone];  //no check mark
        [cell textLabel].textColor = [[UIColor alloc] initWithRed:0.0/255 green:0.0/255 blue:0.0/255 alpha:1.0];  //keep black color

    }
    //else retrieve information from the array and update the cell's accessory
    else{
        //if the cell is in your array, add a checkbox
        [cell setAccessoryType:UITableViewCellAccessoryCheckmark];  //add check box
        [cell textLabel].textColor = [[UIColor alloc] initWithRed:50.0/255 green:79.0/255 blue:133.0/255 alpha:1.0];  //change color of text label
        //if the cell is not in your array, then keep standard format
        [cell setAccessoryType:UITableViewCellAccessoryNone];  //no check mark
        [cell textLabel].textColor = [[UIColor alloc] initWithRed:0.0/255 green:0.0/255 blue:0.0/255 alpha:1.0];  //keep black color

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文