删除选定行的对象

Posted

技术标签:

【中文标题】删除选定行的对象【英文标题】:remove objects of selected row 【发布时间】:2014-08-01 21:19:27 【问题描述】:

嘿,我创建了一个带有多项选择和复选标记附件的表格视图,用户可以点击并选择表格中的相关行...单独选择的 Retailerid 和 Retailernaem 将存储在 NSMutableDictionary 中,所有字典作为回报将存储在NSMutableArray...我一直这样做到现在

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 

UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];

if ([selectedCell accessoryType] == UITableViewCellAccessoryNone) 
    [selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];

    NSMutableDictionary *theDictionary = [[NSMutableDictionary alloc] init];

    [theDictionary setObject:[[BrandsArray valueForKey:@"RetailerID"] objectAtIndex:indexPath.row] forKey:@"id"];

    [theDictionary setObject:[[BrandsArray valueForKey:@"RetailerName"] objectAtIndex:indexPath.row] forKey:@"name"];

    [selectedIndexes addObject:theDictionary];


else 
    [selectedCell setAccessoryType:UITableViewCellAccessoryNone];
    NSLog(@"this is deselected row %@",[selectedIndexes objectAtIndex:indexPath.row]);
    NSMutableDictionary *dictionary = [selectedIndexes objectAtIndex:indexPath.row];

    [selectedIndexes removeObject:dictionary];

    dictionary = nil;


[tableView deselectRowAtIndexPath:indexPath animated:NO];


现在问题出在 else 块中...它没有从随机选择的行中删除对象... 例如,如果我选择第一行然后取消选择相同的,它工作正常但是当我选择最后一行然后取消选择同一个应用程序崩溃..

【问题讨论】:

删除对象后是否尝试过[tableview reloadData]? 您的方法有缺陷 - 您的 selectedIndexes 数组将不包含与您的数据模型相同数量或顺序的元素。您应该使用NSMutableIndexSet。在这里查看我的答案-***.com/questions/25050337/… 应用程序在我取消选择行时崩溃,因此无法调用 [tableview reloadData]。 @kkocabiyik @Paulw11 我正在看 【参考方案1】:

由于my other answer处理了多个部分,我将在此处提供一个更简单的单个部分的答案

首先,为您的选择状态声明一个属性 -

@property (strong,nonatomic) NSMutableIndexSet *selectStates;

viewDidLoad初始化它

self.selectStates=[NSMutableIndexSet new];

didSelectRowAtIndexPath中使用它-

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 


    UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];

    if ([self.selectStates containsIndex:[indexPath.row]) 
        [selectedCell setAccessoryType:UITableViewCellAccessoryNone]; 
        [self.selectStates removeIndex:indexPath.row];
     else 
        [selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];
        [self.selectStates addIndex:indexPath.row];
    

    [tableView deselectRowAtIndexPath:indexPath animated:NO];

当单元格滚动回视图时,您还需要检查cellForRowAtIndexPath 中的selectedStates 以设置正确的附件。只需添加 sn-p -

if ([self.selectStates containsIndex:[indexPath.row]) 
     [cell setAccessoryType:UITableViewCellAccessoryNone]; 
 else 
     [cell setAccessoryType:UITableViewCellAccessoryCheckmark];

如果您需要能够轻松插入和删除行,那么您可以使用NSMutableSet 而不是NSIndexSet - 只需存储数据源对象。如果您确实允许删除,则需要确保在删除该行时从集合中删除该对象(如有必要)。

首先,为您的选择状态声明一个属性 -

@property (strong,nonatomic) NSMutableSet *selectStates;

viewDidLoad初始化它

self.selectStates=[NSMutableSet new];

didSelectRowAtIndexPath使用它-

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 


    UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];

    Brand *brand=(Brand *)[BrandsArray objectAtIndex:indexPath.row];  // Change "Brand" to the appropriate object class

    if ([self.selectStates containsObject:brand) 
        [selectedCell setAccessoryType:UITableViewCellAccessoryNone]; 
        [self.selectStates removeObject:brand];
     else 
        [selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];
        [self.selectStates addObject:brand];
    

    [tableView deselectRowAtIndexPath:indexPath animated:NO];

您还需要检查cellForRowAtIndexPath 中的selectedStates 以在单元格滚动回视图时设置正确的附件。只需添加 sn-p -

if ([self.selectStates containsObject:brand) 
     [cell setAccessoryType:UITableViewCellAccessoryNone]; 
 else 
     [cell setAccessoryType:UITableViewCellAccessoryCheckmark];

【讨论】:

抱歉回复晚了,但我从中获取表数据的服务器已关闭。我将在服务器再次运行时测试您的方法... 你能给我解释一下 NSMutableIndexSet... 里面存储了什么值。以及这一行发生了什么:self.selectStates=[NSMutableIndexSet new]; 一个索引集只包含一组索引——实际上是整数。您可以快速测试该集合是否包含给定索引。这条线只是说[[NSMutableIndexSet alloc]init]的更新,更快的方式@ 在这种情况下它会起作用,但总的来说,我不确定使用 NSMutableIndexSet 作为表视图的数据源是否是个好主意。想想当用户想要删除购物清单应用中的第一行时会发生什么。 这是一个好点,我只是在想。您可以只使用 NSSet - 它在搜索和内存方面更昂贵,但不会产生影响。我将更新我的答案以显示如何【参考方案2】:

问题在于你使用数组的方式。

假设您从包含 10 个单元格的表格视图中选择了最后一个元素。那么数组大小为1,但是当你再次选择最后一行时,[selectedIndexes objectAtIndex:indexPath.row];正在尝试访问数组中索引为 9 的元素,该元素目前不存在。

尝试实现这样的东西:

NSInteger ARRAY_INITIAL_SIZE = 100;

NSMutableArray *selectedIndexes = [NSMutableArray arrayWithCapacity:ARRAY_INITIAL_SIZE];

for (NSInteger i = 0; i < ARRAY_INITIAL_SIZE; ++i) 
    selectedIndexes[i] = [NSNull null];

将 selectedIndexes 设置为 View Controller 类中的一个属性,并且无论何时使用它,都应使用 self.selectedIndexes。

在didSelectRow:atIndexPath:方法中,第一行推荐为:

[tableView deselectRowAtIndexPath:indexPath animated:NO];

然后,编写代码:

UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];

if ([selectedCell accessoryType] == UITableViewCellAccessoryNone) 

    selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;

    NSMutableDictionary *theDictionary = [NSMutableDictionary dictionary];

    [theDictionary setObject:[[BrandsArray valueForKey:@"RetailerID"] objectAtIndex:indexPath.row] forKey:@"id"];

    [theDictionary setObject:[[BrandsArray valueForKey:@"RetailerName"] objectAtIndex:indexPath.row] forKey:@"name"];

    [selectedIndexes replaceObjectAtIndex:indexPath.row withObject:theDictionary];

 else 

    selectedCell.accessoryType = UITableViewCellAccessoryNone;

    [selectedIndexes replaceObjectAtIndex:indexPath.row withObject:[NSNull null]];


希望对你有帮助。告诉我。

【讨论】:

是的@Pavlusha 我知道问题但不知道解决方案...!! 或者使用 NSMutableIndexSet 并将整个混乱减少到大约 4 行。除了数组的问题之外,还有使用单元格的当前accessoryType 的问题 - 一旦重新使用单元格,这将无效 我只是试图解释一下应用程序崩溃的原因,以及他如何使用他想要使用的方法来纠正它。 但是当表中有 101 行时,您的方法会崩溃 - 或者如果您将数组增加到 1000,那么它将在 1001 时崩溃并浪费内存。 抱歉回复晚了,但我认为我从中获取表数据的服务器已关闭。当服务器再次运行时,我将测试您的方法...

以上是关于删除选定行的对象的主要内容,如果未能解决你的问题,请参考以下文章

如何从 agggrid 中的选定行中删除蓝色

Vue.js - 如何通过 tbody 中的删除按钮删除选定的行?

如何使用 javascript 或 html 按钮删除选定的表格行?

选定行的悬停禁用引导表

让用户删除选定的结构 js 对象

从角度的下拉列表中删除选定的选项