web-dev-qa-db-fra.com

Menu contextuel iOS13 Comment afficher ou naviguer vers la vue furtive actuelle lorsque vous appuyez dessus

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:

Aperçu et vue du men

Vue Collection

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.

9
flora liu

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)
    }
}
7
Andrew Bennet

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)
    }
}
0
alobaili