У меня возникла проблема с анимацией добавления или удаления строки в UITableView, которая имеет разную высоту, чем другие строки.
Следующие gif демонстрируют проблему с строками высоты по умолчанию (44pts) и большей строкой (100pt), которые вставлены и удалены. Слева - экранная запись с симулятора (новая ячейка, заканчивающаяся пятой пятой, является другой проблемой), а одна справа - макет того, что он должен делать.
В моем случае у меня есть ряд строк, каждый из которых занимает 60 пунктов. Когда нажата кнопка в ячейке, ячейка "редактирования" выскользнет снизу, нажав нижние ячейки вниз. Эта ячейка редактирования высотой 180pts. Когда я вызываю insertRowsAtIndexPaths:withRowAnimation:
или deleteRowsAtIndexPaths:withRowAnimation:
, анимация предполагает неправильную высоту 60pts, вместо 180pts она должна быть
Это означает, что в случае UITableViewRowAnimationTop
новая ячейка появится на -60pts с позиции, в которой она закончится, и переместится в новое положение; около трети анимации он должен делать. Между тем, строка ниже анимирует плавно от ее начального положения до 180 пунктов вниз, точно так, как должна.
Кто-нибудь разработал реальное решение? каким-то образом рассказать новую строку, какую высоту она должна быть для анимации?
Ниже приведен код, который я использую, чтобы скрыть и показать строку редактирования. Я использую TLSwipeForOptionsCell
для запуска редактирования, но он легко реплицируется с использованием, например, tableView:didSelectRowAtIndexPath:
-(void)hideEditFields{
[self.tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForItem:editFormVisibleForRow+1 inSection:0]] withRowAnimation:UITableViewRowAnimationTop];
editFormVisibleForRow = -1;
[self.tableView endUpdates];
}
-(void)cellDidSelectMore:(TLSwipeForOptionsCell *)cell{
NSIndexPath* indexPath = [self.tableView indexPathForCell:cell];
// do nothing if this is the currently selected row
if(editFormVisibleForRow != indexPath.row){
if(editFormVisibleForRow >= 0){
[self hideEditFields];
// update the index path, as the cell positions (may) have changed
indexPath = [self.tableView indexPathForCell:cell];
}
[self.tableView beginUpdates];
editFormVisibleForRow = indexPath.row;
[self.tableView insertRowsAtIndexPaths:@[
[NSIndexPath indexPathForItem:editFormVisibleForRow+1 inSection:0]
] withRowAnimation:UITableViewRowAnimationTop];
[self.tableView endUpdates];
}
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return _dataSource.count + (editFormVisibleForRow >= 0 ? 1 : 0);
}
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
int row = indexPath.row;
if(editFormVisibleForRow >= 0 && row > editFormVisibleForRow && row <= editFormVisibleForRow + 1){
return 180.0f;
}
else return 60.0;
}
Похоже, что это обычная проблема без четкого ответа. Большинство подобных вопросов, которые я нашел здесь, на SO, остаются без ответа или предлагают обходные пути, характерные для ситуации с аськой. (примеры: Проблема с RowAnimation, Пользовательская высота UITableViewCell дает неправильную анимацию, Сбой анимации UITableView при удалении и вставке ячеек с разной высотой).
Кроме того, вместо того, чтобы пытаться сделать одну строку с тремя размерами, я попытался сделать три более мелкие строки и оживить их, но это не подходит, потому что все они появились сразу. Я также попытался оживить их один за другим, но облегчение сделало его странным, с очевидной 3-шаговой анимацией, вместо того, чтобы весь вид редактирования скользил из вида одним движением.
Изменить: Я только заметил, что если я вызываю reloadRowsAtIndexPaths:withRowAnimation: UITableViewRowAnimationNone
для строки выше той, которую я пытаюсь оживить, она изменяет поведение анимации; а именно анимация предполагает, что высота равна 0pts, как показано в следующей анимации. Это ближе к тому, что я хочу, но все же не так, поскольку скорость анимации неверна и она оставляет пробел (в моем приложении это означает фон
цвет прорывается)