Reputation: 371
I have a NSmutableDictionary which I use it to fill in the tableView. Now I want to make the rows in my tableView editable. Here is my code:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
And when one select the row
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
//Below four lines to get the name of course to delete
NSString *key = [[self sectionKeys] objectAtIndex:[indexPath section]];//This is the key
NSArray *contents = [[self sectionContents] objectForKey:key];
NSString *contentForThisRow = [contents objectAtIndex:[indexPath row]];//This is the value
[_sectionContents removeObjectForKey:key];//this can delete the key,not fit here, should delete value
NSLog(@"Dictionary: %@", [_sectionContents description]);//test dictionary here
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
Here, my situation is one key may have more than one values, so when user select the row to delete, above code will delete the whole key with other values, which is not what I want, and it also generate error.
So my question is instead of using removeObjectForKey
, what is the correct way to only remove value but not key from the dictionary please?
Here is the code I populate my dictionary:
//New code for populating dictionary
if ([_sectionContents objectForKey:AddKey] != nil) {
//Already exist a value for the key
id object = [_sectionContents objectForKey:AddKey];
NSMutableArray *objectArray;
//objectArray = [[NSMutableArray alloc] init];
if ([object isKindOfClass:[NSMutableArray class]]) {//if object is a mutableArray already
objectArray = (NSMutableArray *)object;
//NSLog(@"1.The code runs through here!");
} else {//If object is not array, it means that only one value exists here.
//The following convert string to correct format
NSString *oldCourse=nil;
if ([object isKindOfClass:[NSString class]]) {
oldCourse = object;
} else if ([object respondsToSelector:@selector(stringValue)]) {
oldCourse = [object stringValue];
} else if ([object respondsToSelector:@selector(description)]) {
oldCourse = [object description];
}
NSString *newString = [[oldCourse componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@" "];//remove newline
NSString * newString2 = [newString substringWithRange:NSMakeRange(7, [newString length]-7)];//cut the front
//To erase the symbols
NSString *newString3 = [newString2 stringByReplacingOccurrencesOfString:@")" withString:@""];
NSString *newString4 = [newString3 stringByReplacingOccurrencesOfString:@"\"" withString:@""];
//NSLog(@"%@",newString4);
//if ([oldCourse isKindOfClass:[NSString class]])
//NSLog(@"Become string here!");
objectArray = [[NSMutableArray alloc] init];
if(![objectArray containsObject:newString4])
if(![_msgCourse containsObject:newString4])
[objectArray insertObject:newString4 atIndex:0];
// NSLog(@"2.The code runs through here!");
//NSMutableArray *objectArray = [[NSMutableArray alloc] init];
}
NSLog(@"%@",objectArray);
NSString *message;
if([objectArray containsObject:course])//Giving out warning if course retaken
{UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Error: this course have been selected already." message:message delegate:nil cancelButtonTitle:@"Return to course planner" otherButtonTitles:nil, nil];
[alert show];}
if(![objectArray containsObject:course] && ![course isEqualToString:[objectArray objectAtIndex:0]] &&
![_msgCourse containsObject:course])
[objectArray addObject:course];
if(![_msgCourse containsObject:course])//Use this flag to avoid retake class
[_msgCourse addObject:course];
//NSLog(@"3.The code runs through here!");
[_sectionContents setObject:objectArray forKey:AddKey];
} else {
//No value for the key, add new value
NSString *message;
if([_msgCourse containsObject:course])//If course existed
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Error: this course have been selected already." message:message delegate:nil cancelButtonTitle:@"Return to course planner" otherButtonTitles:nil, nil];
[alert show];
}
if(![_msgCourse containsObject:course])
{
[_sectionContents setObject:[NSArray arrayWithObjects:course,nil] forKey:AddKey];
[_msgCourse addObject:course];
}
}
Upvotes: 2
Views: 794
Reputation: 285
If I understood correctly, you trying to remove element from section, but actually deleting the whole section. You should do next:
NSString *key = [_sectionKeys objectAtIndex:[indexPath section]];//This is the key
NSMutableArray *contents = _sectionContents[key];
//Delete only selected row
[contents removeObjectAtIndex:indexPath.row]
This should work.
Upvotes: 3
Reputation: 32066
Since the values of your key-value pairs are arrays: NSArray *contents = [[self sectionContents] objectForKey:key];
, what you actually need to know is how to remove an element from an array.
This is simply:
//Need a mutable version. I've assumed it isn't already mutable. If it is, you can
//adjust accordingly.
NSMutableArray *contents = [[self sectionContents][key] mutableCopy];
id object = /* You need to determine which element to remove */;
[contents removeObject:object];
//Put the modified array back into the dictionary
[self sectionContents][key] = contents;
Upvotes: 3