Приложение вылетает при вызове "tableView endUpdates"
В настоящее время я работаю над реализацией встроенного средства выбора UIDate внутри UITableViewCell.
Я могу показать и скрыть эту ячейку выбора, когда выбираю ячейку прямо над тем местом, где эта ячейка должна быть вставлена, и это то поведение, которое я ожидаю. Однако приложение вылетает, если я выбираю любые другие ячейки в табличном представлении:
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3318.16.14/UITableView.m:1582
Посмотрев принятый ответ на этот вопрос SO, я добавил точку останова исключения, и я обнаружил, что приложение вызывает сбой при вызове [tableView endUpdates];
в didSelectRowAtIndexPath
:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
// Check to see if the "Only Alert From" row was selected. The cell with the picker should be below this one.
if (indexPath.section == TimeOfDaySection && indexPath.row == HourTimeZoneRow && self.timePickerIsShowing == NO){
[tableView beginUpdates];
[self showTimePicker];
[tableView endUpdates];
} else{
[tableView beginUpdates];
[self hideTimePicker];
[tableView endUpdates];
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Тем не менее, я не уверен, как поступить. Если я закомментирую звонок [tableView endUpdates];
приложение не будет зависать при выборе других ячеек, НО ячейка с видом средства выбора не будет скрыта. У кого-нибудь есть предложения? Спасибо!
РЕДАКТИРОВАТЬ: ниже мой код для showTimePicker
а также hideTimePicker
:
- (void)showTimePicker
{
self.timePickerIsShowing = YES;
self.timePicker.hidden = NO;
//Create the index path where we insert the cell with the picker
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:HourTimeZoneRow + 1 inSection:TimeOfDaySection];
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
self.timePicker.alpha = 0.0f;
[UIView animateWithDuration:0.25 animations:^{
self.timePicker.alpha = 1.0f;
//This is the row where the picker cell should be inserted
[self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:HourTimeZoneRow + 1 inSection:TimeOfDaySection]] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView reloadData];
}];
}
- (void)hideTimePicker {
self.timePickerIsShowing = NO;
self.timePicker.hidden = YES;
//Create the index path where we delete the cell with the picker
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:HourTimeZoneRow + 1 inSection:TimeOfDaySection];
[self.tableView beginUpdates];
//Delete the picker row
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
[UIView animateWithDuration:0.25
animations:^{
self.timePicker.alpha = 0.0f;
}
completion:^(BOOL finished){
self.timePicker.hidden = YES;
}];
}
РЕДАКТИРОВАТЬ 2: После прочтения этой темы я думаю, что проблема может быть с моим numberOfRowsInSection
метод:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
switch (section) {
case NotificationsSection:
return TotalPreferencesRows;
break;
case RedZoneSection:
return TotalRedZoneRows;
break;
case TimeOfDaySection:
if (self.timePickerIsShowing) {
return TotalTimeOfDayRows + 1;
}
// else if (self.timePickerIsShowing == NO){
// return TotalTimeOfDayRows;
// }
else{
return TotalTimeOfDayRows;
}
return TotalTimeOfDayRows;
break;
default:
return 0;
break;
}
}
2 ответа
Проблема в вашем didSelectRowAtIndexPath, вы вызываете метод hide, даже если он может не отображаться. Сделать else
пункт в else if
, как это:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
// Check to see if the "Only Alert From" row was selected. The cell with the picker should be below this one.
if (indexPath.section == TimeOfDaySection && indexPath.row == HourTimeZoneRow && self.timePickerIsShowing == NO){
[tableView beginUpdates];
[self showTimePicker];
[tableView endUpdates];
} else if (indexPath.section == TimeOfDaySection && indexPath.row == HourTimeZoneRow && self.timePickerIsShowing == YES){
[tableView beginUpdates];
[self hideTimePicker];
[tableView endUpdates];
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Не уверен, что это является причиной сбоя, но не рекомендуется вызывать beginUpdates несколько раз, что вы делаете в[tableView beginUpdates];
[self showTimePicker];
[tableView endUpdates];
потому что showTimePicker вызывает [self.tableView beginUpdates];