Странная анимация при удалении элемента из UICollectionView, когда отображается UIContextMenu
Я использую UIContextMenuInteraction
чтобы показать контекстное меню для UICollectionView
следующее:
func collectiovnView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
return UIContextMenuConfiguration(identifier: nil, previewProvider: nil, actionProvider: { _ in
let deleteAction = UIAction(title: "Delete", image: UIImage(systemName: "trash"), attributes: .destructive) { _ in
self.deleteItem(at: indexPath)
}
return UIMenu(title: "Actions", children: [deleteAction])
})
}
func deleteItem(at indexPath: IndexPath) {
self.collectionView.performBatchUpdates({
self.items.remove(at: indexPath.item)
self.collectionView.deleteItems(at: [indexPath])
})
}
Все работает хорошо, но когда я нажимаю "Удалить", происходит странная анимация, когда удаленный элемент остается на своем месте, пока другие элементы перемещаются, а затем мгновенно исчезает. А иногда я даже вижу пустое место или случайный элемент за долю секунды до появления нового элемента.
Если я позвоню collectionView.deleteItems()
пока контекстное меню не отображается, анимация удаления работает должным образом.
1 ответ
Похоже, что странная анимация является результатом конфликта между двумя анимациями, которые выполняются почти одновременно:
- Анимация удаления: при нажатии на элемент "Удалить"
collectionView.deleteItems()
вызывается, и указанный элемент коллекции удаляется с анимацией. - Анимация закрытия меню: после нажатия на пункт меню контекстное меню также закрывается с другой анимацией, которая показывает удаленный элемент в течение доли секунды.
Похоже, это ошибка, которую Apple должна исправить. Но в качестве обходного пути мне пришлось отложить удаление до завершения анимации закрытия:
func deleteItem(at indexPath: IndexPath) {
let delay = 0.4 // Seconds
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
self.collectionView.performBatchUpdates({
self.items.remove(at: indexPath.item)
self.collectionView.deleteItems(at: [indexPath])
})
}
}
В 0.4
секунды - это самая короткая задержка, которая сработала для меня.