J'essaie d'implémenter "Menu contextuel" dans iOS13 dans une vue de table (vue de collection essayée également, ils ont le même problème):
J'ai suivi les instructions ici , créé une vue de collection avec un tas de photos, et quand 3d touch, j'obtiendrai un aperçu avec une liste d'actions, comme ceci:
La méthode déléguée dans UITableView:
- (void)tableView:(UITableView *)tableView willCommitMenuWithAnimator:
(id<UIContextMenuInteractionCommitAnimating>)animator;
et en collectionVoir
- (void)collectionView:(UICollectionView *)collectionView willCommitMenuWithAnimator:
(id<UIContextMenuInteractionCommitAnimating>)animator;
les deux n'ont pas "indexPath
";
Il n'y a donc aucun moyen pour moi de passer dans la cellule ou l'index actuel que je regarde.
Je veux implémenter cette méthode déléguée, donc lorsque je tape sur l'image d'aperçu, elle naviguera jusqu'à la page attendue avec des informations liées à la cellule actuelle.
Ce que je veux et j'ai essayé, c'est quelque chose comme ceci:
func collectionView(_ collectionView: UICollectionView, willCommitMenuWithAnimator animator: UIContextMenuInteractionCommitAnimating) {
animator.addAnimations {
self.show(PreviewViewController(image: UIImage(named: "indexpathString")), sender: self)
}
}
et le indexpathString
est lié à la cellule ou à la collection actuellement sélectionnée, je peux donc lancer le viewController en fonction de celui-ci.
Veuillez me faire savoir s'il existe un autre moyen de procéder.
La fonction contextMenuInteraction(_:willCommitWithAnimator:)
semble avoir été remplacée par tableView(_:willPerformPreviewActionForMenuWith:animator:)
, qui fournit le UIContextMenuConfiguration
associé au présenté menu. Au moment où votre menu est présenté, attribuez un identifiant qui vous permettra d'identifier la ligne. L'identifiant doit être n'importe quel objet NSCopying
- par exemple un NSIndexPath
:
override func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
// Pass the indexPath as the identifier for the menu configuration
return UIContextMenuConfiguration(identifier: indexPath as NSIndexPath, previewProvider: nil) { _ in
// Empty menu for demonstration purposes
return UIMenu(title: "", children: [])
}
}
puis utilisez cet identifiant dans le willPerformPreviewActionForMenuWith:animator:
fonction:
override func tableView(_ tableView: UITableView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) {
guard let indexPath = configuration.identifier as? IndexPath else { return }
// Use your index path to get your destination VC in some way; arbitrary example shown...
let destinationVc = destinationViewController(for: indexPath)
// Then animate the appearance of the VC with the provided animator
animator.addAnimations {
self.show(destinationVc, sender: self)
}
}
Il y a une propriété dans le animator
appelée previewViewController
qui est de type UIViewController?
. C'est le même que le previewProvider
que vous définissez dans tableView(_:contextMenuConfigurationForRowAt:point:)
, donc si vous définissez le previewProvider
comme contrôleur de vue de destination, vous pouvez faire quelque chose comme ceci:
Définissez votre previewProvider
override func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
return UIContextMenuConfiguration(identifier: nil, previewProvider: { () -> UIViewController? in
let string = yourDataSource[indexPath.row]
return PreviewViewController(image: UIImage(named: string))
})
// actionProvider has a default value of nil, so you can omit it
}
tilisez l'animateur pour le montrer
override func tableView(_ tableView: UITableView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) {
guard let destinationViewController = animator.previewViewController else { return }
animator.addAnimations {
self.show(destinationViewController, sender: self)
}
}