Столбец падает при перемещении более половины ячеек в другой раздел
В основном, я пытаюсь написать приложение с табличным представлением с двумя разделами: одно с незавершенными задачами (ячейками), а другое с завершенными. Каждая ячейка имеет подклассу UIButton. Проблема заключается в том, что он выходит из строя с исключением NSRangeException, когда я проверяю более половины элементов. Я был бы очень признателен за любые советы по этой проблеме.
Ошибка: * Завершение приложения из-за неперехваченного исключения 'NSRangeException', причина: '* - [__ NSArrayM objectAtIndex:]: индекс 9 за пределами границ [0.. 8]'
Метод CheckMarkTapped (вызов для переключения элемента):
-(void)checkMarkTapped:(UIButton *)sender {
UITableViewCell *cell = ((UITableViewCell *)[sender superview]);
NSIndexPath *originIndexPath = [self.tableView indexPathForCell:cell];
NSIndexPath *destinationIndexPath;
NSLog(@"originIndexPath row: %i, section: %i", originIndexPath.row, originIndexPath.section);
[self fixAllCheckboxes];
if (originIndexPath.section == 0) {
destinationIndexPath = [NSIndexPath indexPathForRow:[completedItems count] inSection:1];
[sender setSelected:NO];
NSMutableDictionary *tempDict = [[NSDictionary dictionaryWithDictionary:[uncompletedItems objectAtIndex:originIndexPath.row]]mutableCopy];
[completedItems addObject:tempDict];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObjects:destinationIndexPath, nil] withRowAnimation:UITableViewRowAnimationLeft];
[uncompletedItems removeObjectAtIndex:originIndexPath.row];
}
if (originIndexPath.section == 1) { //if the checkbox is in section 1
[sender setSelected:YES];
NSMutableDictionary *tempDict = [NSDictionary dictionaryWithDictionary:[[completedItems objectAtIndex:originIndexPath.row]mutableCopy]];
destinationIndexPath = [NSIndexPath indexPathForRow:[[tempDict objectForKey:@"index"]intValue] inSection:0];
[uncompletedItems insertObject:tempDict atIndex:[[tempDict objectForKey:@"index"]intValue]];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObjects:destinationIndexPath, nil] withRowAnimation:UITableViewRowAnimationLeft];
[completedItems removeObjectAtIndex:[self.tableView indexPathForCell:cell].row];
}
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:originIndexPath, nil] withRowAnimation:UITableViewRowAnimationLeft];
}
Метод CELLFORROWATINDEXPATH:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
if (indexPath.section == 1) {
CellIdentifier = @"Cell1";
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.showsReorderControl = YES;
}
for (UIControl *checkbox in [cell subviews]) {
if (checkbox.tag == 9001) {
[checkbox removeFromSuperview];
}
}
if (indexPath.section == 0) {
UIButton *checkbox = [[UIButton alloc]initWithFrame:CGRectMake(5, 5, 40, 40)];
[checkbox addTarget:self action:@selector(checkMarkTapped:) forControlEvents:UIControlEventTouchUpInside];
[cell setIndentationWidth:45];
[cell setIndentationLevel:1];
[checkbox setTag:9001];
[checkbox setImage:[UIImage imageNamed:@"unchecked"] forState:UIControlStateNormal];
[checkbox setImage:[UIImage imageNamed:@"checked"] forState:UIControlStateSelected];
[cell addSubview:checkbox];
cell.textLabel.backgroundColor = [UIColor whiteColor];
cell.textLabel.backgroundColor = [UIColor whiteColor];
cell.contentView.backgroundColor = [UIColor whiteColor];
cell.textLabel.font = [UIFont boldSystemFontOfSize:20];
switch (indexPath.section) {
case 0:
cell.textLabel.text = [[uncompletedItems objectAtIndex:indexPath.row]objectForKey:@"Name"];
break;
case 1:
cell.textLabel.text = [[completedItems objectAtIndex:indexPath.row]objectForKey:@"Name"];
[checkbox setSelected:YES];
break;
default:
break;
}
[cell addSubview:checkbox];
} else if (indexPath.section == 1) {
UIButton *checkbox = [[UIButton alloc]initWithFrame:CGRectMake(5, 5, 40, 40)];
[checkbox addTarget:self action:@selector(checkMarkTapped:) forControlEvents:UIControlEventTouchUpInside];
[cell setIndentationWidth:45];
[cell setIndentationLevel:1];
[checkbox setTag:9001];
cell.textLabel.backgroundColor = [UIColor whiteColor];
cell.textLabel.backgroundColor = [UIColor whiteColor];
cell.contentView.backgroundColor = [UIColor whiteColor];
cell.textLabel.font = [UIFont boldSystemFontOfSize:20];
cell.textLabel.text = [[uncompletedItems objectAtIndex:indexPath.row]objectForKey:@"Name"];
[checkbox setImage:[UIImage imageNamed:@"unchecked"] forState:UIControlStateNormal];
[checkbox setImage:[UIImage imageNamed:@"checked"] forState:UIControlStateSelected];
[cell addSubview:checkbox];
switch (indexPath.section) {
case 0:
cell.textLabel.text = [[uncompletedItems objectAtIndex:indexPath.row]objectForKey:@"Name"];
break;
case 1:
cell.textLabel.text = [[completedItems objectAtIndex:indexPath.row]objectForKey:@"Name"];
[checkbox setSelected:YES];
break;
default:
break;
}
[cell addSubview:checkbox];
}
return cell;
}
Вот NSLog для Crash. Как вы можете видеть, это происходит, когда массивы имеют одинаковое количество элементов:
2012-12-26 12:54:44.583 Checklist R4[1128:c07] Destination Row: 0, UnCompleted Count: 19, Completed Count: 1
2012-12-26 12:54:45.034 Checklist R4[1128:c07] Destination Row: 1, UnCompleted Count: 18, Completed Count: 2
2012-12-26 12:54:45.454 Checklist R4[1128:c07] Destination Row: 2, UnCompleted Count: 17, Completed Count: 3
2012-12-26 12:54:45.873 Checklist R4[1128:c07] Destination Row: 3, UnCompleted Count: 16, Completed Count: 4
2012-12-26 12:54:46.294 Checklist R4[1128:c07] Destination Row: 4, UnCompleted Count: 15, Completed Count: 5
2012-12-26 12:54:47.072 Checklist R4[1128:c07] Destination Row: 5, UnCompleted Count: 14, Completed Count: 6
2012-12-26 12:54:47.399 Checklist R4[1128:c07] Destination Row: 6, UnCompleted Count: 13, Completed Count: 7
2012-12-26 12:54:48.085 Checklist R4[1128:c07] Destination Row: 7, UnCompleted Count: 12, Completed Count: 8
2012-12-26 12:54:48.621 Checklist R4[1128:c07] Destination Row: 8, UnCompleted Count: 11, Completed Count: 9
2012-12-26 12:54:49.090 Checklist R4[1128:c07] Destination Row: 9, UnCompleted Count: 10, Completed Count: 10
2012-12-26 12:54:50.234 Checklist R4[1128:c07] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 9 beyond bounds [0 .. 8]'
Ответы
Ответ 1
ваш массив completedItems
или uncompletedItems
, один из которых имеет только 8 элементов, но вы пытаетесь получить доступ к элементу больше, чем это. Проверьте свой метод numberOfRowsInSection
, укажите их динамическое значение, например
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int rowCount = 0;
if (section == 0) {
rowCount = [uncompletedItems count];
} else {
rowCount = [completedItems count];
}
return rowCount;
}
и, кроме того, ему не нужны как switch
, так и if
. Используйте кого-нибудь, чтобы проверить ваш section
на 0 или 1.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
if (indexPath.section == 1) {
CellIdentifier = @"Cell1";
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.showsReorderControl = YES;
}
for (UIControl *checkbox in [cell subviews]) {
if (checkbox.tag == 9001) {
[checkbox removeFromSuperview];
}
}
UIButton *checkbox = [[UIButton alloc]initWithFrame:CGRectMake(5, 5, 40, 40)];
[checkbox addTarget:self action:@selector(checkMarkTapped:) forControlEvents:UIControlEventTouchUpInside];
[cell setIndentationWidth:45];
[cell setIndentationLevel:1];
[checkbox setTag:9001];
[checkbox setImage:[UIImage imageNamed:@"unchecked"] forState:UIControlStateNormal];
[checkbox setImage:[UIImage imageNamed:@"checked"] forState:UIControlStateSelected];
[cell addSubview:checkbox];
cell.textLabel.backgroundColor = [UIColor whiteColor];
cell.textLabel.backgroundColor = [UIColor whiteColor];
cell.contentView.backgroundColor = [UIColor whiteColor];
cell.textLabel.font = [UIFont boldSystemFontOfSize:20];
switch (indexPath.section) {
case 0:
cell.textLabel.text = [[uncompletedItems objectAtIndex:indexPath.row]objectForKey:@"Name"];
break;
case 1:
cell.textLabel.text = [[completedItems objectAtIndex:indexPath.row]objectForKey:@"Name"];
[checkbox setSelected:YES];
break;
default:
break;
}
[cell addSubview:checkbox];
return cell;
}
Ответ 2
В вашем коде могут быть две проблемы.
-
You are returning numbers of rows to Table View less then your array
count.
-
Your array is exceeding from the numbers of rows in Table
View.
В приведенном ниже описании error
ясно показано, что ваш массив имеет индексы 8
, но вы обращаетесь к 9th
, который вызывает ошибку.