iOS UItableView通过索引路径从数组中删除对象

时间:2015-04-09 18:05:45

标签: ios objective-c arrays uitableview

我有按A-Z部分排序的自定义联系簿。我正在尝试添加一个阵列选择的联系人

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

NSMutableDictionary *contactInfo = [NSMutableDictionary new];

Cell *cell = (Cell *)[self.contTableView cellForRowAtIndexPath:indexPath];

//NSLog(@"CELL %@", cell.contact.fullname);

if (!cell.contact.contactChecked) {

    cell.contactImage.image = [UIImage imageNamed:@"cell_blue_circle.png"];
    cell.contact.contactChecked = YES;
    //NSLog(@"DID SELECT %@", cell.contact.fullname);
    NSLog(@"index checked row %d section %d", indexPath.row, indexPath.section);
    [contactInfo setValue:cell.contact.fullname forKey:@"name"];
    [contactInfo setValue:cell.contact.numbers.firstObject forKey:@"phone"];

    [self.seletedPeople insertObject:contactInfo atIndex:indexPath.row];

} else {
     NSLog(@"index unchecked row %d section %d", indexPath.row, indexPath.section);
    cell.contactImage.image = [UIImage imageNamed:@"cell_gray_circle.png"];
    cell.contact.contactChecked = NO;
    [self.seletedPeople removeObjectAtIndex:indexPath.row];
}

NSLog(@"DICT SELECTED %@", self.seletedPeople);

}

在某些单元格应用程序崩溃时出现错误

会发生什么
  

*由于未捕获的异常终止应用' NSRangeException',原因:' * - [__ NSArrayM insertObject:atIndex:]:索引1超出   空数组的界限'   ***首先抛出调用堆栈:(0x29c02fef 0x38150c8b 0x29b1cf8f 0xf7fe9 0x2d36e56b 0x2d41d43b 0x2d2d2a91 0x2d24d38f 0x29bc8fed 0x29bc66ab   0x29bc6ab3 0x29b13201 0x29b13013 0x313f2201 0x2d2b7a59 0x10c075   0x386dcaaf)libc ++ abi.dylib:以未捕获的异常终止   输入NSException

更新:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *cellID = @"Cell";
Cell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath];

if (searchResults) {

    //NSLog(@"CELL %@", cell.contact.fullname);
    contact = [searchResults objectAtIndex:indexPath.row];
    cell.contact = contact;
    cell.firstNameLabel.text = contact.fullname;
    cell.avatar.image = contact.image;
    cell.avatar.layer.borderColor = [UIColor grayColor].CGColor;
    cell.avatar.layer.borderWidth = 0.5;
    cell.avatar.layer.cornerRadius = 25.0;
    cell.avatar.layer.masksToBounds = YES;
    cell.number.text = contact.numbers.firstObject;

} else {

    NSString *sectionTitle = [[[namesDictionary allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]
                              objectAtIndex:indexPath.section];
    NSArray *sectionContacts = [namesDictionary objectForKey:sectionTitle];
    contact = [self getContactFromArray:[sectionContacts objectAtIndex:indexPath.row]];

    cell.firstNameLabel.text = [sectionContacts objectAtIndex:indexPath.row];

    cell.avatar.image = contact.image;
    cell.avatar.layer.borderColor = [UIColor grayColor].CGColor;
    cell.avatar.layer.borderWidth = 0.5;
    cell.avatar.layer.cornerRadius = 25.0;
    cell.avatar.layer.masksToBounds = YES;
    cell.number.text = contact.numbers.firstObject;

    cell.contact = contact;

    cell.tag = indexPath.row;
}

if (contact.contactChecked) {
    cell.contactImage.image = [UIImage imageNamed:@"cell_blue_circle.png"];
} else {
    cell.contactImage.image = [UIImage imageNamed:@"cell_gray_circle.png"];

}


return cell;

}

5 个答案:

答案 0 :(得分:2)

我在这种情况下使用的方式。我创建了一个模型类,并使用模型加载tableview。现在,当我选择一个单元格或取消选择一个单元格。我只是将该模型添加到另一个数组中。之后,当我选择已经选择的单元格时,我可以从indexpath.row获得相同的模型,然后我可以使用NSArray方法在该选定的数组中获取该模型并从那里删除它。要解决您的问题,您可以在选择期间使用indexPath.row作为字典中的另一个键。之后取消选择单元格时,使用谓词从您用于存储所选数组的数组中获取添加的字典。一旦找到它就会从数组中删除它。

答案 1 :(得分:1)

这里的问题是模型与视图对象的耦合,你不应该从视图本身查询某个属性(在你的情况下是Cell)但是检查的联系人应该反映一下它来自数据源对象的模型(您用来提供cellForRowAtIndexPath:的模型,应该从中查询。

否则代码会因为耦合而出错并且不稳定,因为它可能指向空对象

答案 2 :(得分:0)

问题在于:

[self.seletedPeople insertObject:contactInfo atIndex:indexPath.row];

如果selectedPeople为空并且用户点击了第2行,那么它会尝试将contactInfo插入第2行,这超出了空的范围阵列&#34 ;.只需使用addObject:代替。您还需要更改从该数组中删除项目的方式(可能更好地使用字典)。

答案 3 :(得分:0)

解决方案是将联系人记录ID添加到我的字典中,并使用谓词搜索此联系人ID。然后删除它。感谢@jassi

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



    NSMutableDictionary *contactInfo = [NSMutableDictionary new];

    Cell *cell = (Cell *)[tableView cellForRowAtIndexPath:indexPath];

    if (!cell.contact.contactChecked) {

        cell.contactImage.image = [UIImage imageNamed:@"cell_blue_circle.png"];
        cell.contact.contactChecked = YES;
        //NSLog(@"DID SELECT %@", cell.contact.fullname);
        NSLog(@"index checked %@ ", [indexPath description]);
        [contactInfo setValue:cell.contact.fullname forKey:@"name"];
        [contactInfo setValue:cell.contact.numbers.firstObject forKey:@"phone"];
        [contactInfo setValue:@(cell.contact.contactId) forKey:@"contactId"];


        [self.seletedPeople addObject:contactInfo];

    } else {
         NSLog(@"index unchecked %@", [indexPath description]);
        cell.contactImage.image = [UIImage imageNamed:@"cell_gray_circle.png"];
        cell.contact.contactChecked = NO;
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"contactId == %d", cell.contact.contactId];
        NSArray *resultTemp = [self.seletedPeople filteredArrayUsingPredicate:predicate];

    if(resultTemp.count>0)
        [self.seletedPeople removeObject:resultTemp[0]];


    }

    NSLog(@"DICT SELECTED %@", self.seletedPeople);
}

答案 4 :(得分:-1)

正如user2320861所说,问题出在你使用insertObject的行上。我会做以下事情:

  1. 使用以下代码将self.selectedPeople更改为NSMutableDictionary:

    //in your @interface
    @property (nonatomic, strong) NSMutableDictionary *selectedPeople;
    
  2. 将didSelectCellAtIndexPath中的代码更改为:

    //Since phone numbers are unique.
    self.selectedPeople[cell.contact.numbers.firstObject] = contactInfo;
    
  3. 稍后使用此代码检索所有联系人:

    for(id key in self.selectedPeople) {
        NSDictionary contactInfo = [self.selectedPeople objectForKey:key];
        //Do something with that contactInfo
    }