Сбой анимации при удалении элемента UICollectionViewDiffableDataSource из контекстного меню
Я принял новый UICollectionViewDiffableDataSource. Я применяю снимок источника данных каждый раз, когда удаляю элемент:
var snapshot = NSDiffableDataSourceSnapshot<Int, Item>()
snapshot.appendSections([0])
snapshot.appendItems(items)
apply(snapshot, animatingDifferences: true)
Удаление предлагается с помощью встроенной опции конфигурации представления коллекции:
func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
guard let item = dataSource.itemIdentifier(for: indexPath) else {
return nil
}
let configuration = UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { _ in
let delete = UIAction(title: "Delete", image: UIImage(systemName: "trash.fill"), attributes: .destructive) { _ in
self.deleteItem(item)
}
return UIMenu(title: "", image: nil, identifier: nil, children: [delete])
}
return configuration
}
Если я удалю элемент вне контекстного меню, анимация будет работать отлично. Если я удаляю из контекстного меню, одна ячейка исчезает, а затем мигает следующая. Я подозреваю, что существует какой-то конфликт между закрытием контекстного меню и запуском анимации удаления. Я ищу способ обойти это.
1 ответ
edit: Это было очень стабильно, что приводило к зависанию пользовательского интерфейса и другим странным сбоям, когда он иногда не реагировал на долгое нажатие, не используйте это. Хотелось бы, чтобы в этом API не было такого сбоя, это очень раздражает.
Я тоже нашел этот уродливый сбой и был очень близок к тому, чтобы сдаться, пока не подумал, что попробую реализовать другой API взаимодействия вместо встроенного в UICollectionView
, как ни странно, анимация исчезла.
Сначала добавьте взаимодействие к своим ячейкам contentView
let interaction = UIContextMenuInteraction(delegate: self)
cell.contentView.addInteraction(interaction)
Затем реализуйте делегат, предположительно там, где вы представляете ячейку, в моем случае в viewController
extension ViewController : UIContextMenuInteractionDelegate {
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
// loop through all visible cells to find which one we interacted with
guard let cell = collectionView.visibleCells.first(where: { $0.contentView == interaction.view }) else {
return nil
}
// convert it to an indexPath
guard let indexPath = collectionView.indexPath(for: cell) else {
return nil
}
// continue with your magic!
}
}
И вуаля, вот и все, больше никакой глючной анимации. Я не знаю, есть ли какие-нибудь крайние случаи, когда будет выбрана неправильная ячейка или другие странные вещи, но, похоже, это работает нормально.