私はiOS13の「コンテキストメニュー」をテーブルビューに実装しようとしています(コレクションビューも試してみましたが、同じ問題があります)。
私は here の指示に従い、たくさんの写真を含むコレクションビューを作成しました。3Dタッチすると、次のようなアクションリストのプレビューが表示されます。
UITableViewのデリゲートメソッド:
- (void)tableView:(UITableView *)tableView willCommitMenuWithAnimator:
(id<UIContextMenuInteractionCommitAnimating>)animator;
そしてcollectionView
- (void)collectionView:(UICollectionView *)collectionView willCommitMenuWithAnimator:
(id<UIContextMenuInteractionCommitAnimating>)animator;
どちらにも「indexPath
」はありません。
したがって、私が覗いている現在のセルまたはインデックスを渡す方法はありません。
このデリゲートメソッドを実装したいので、プレビュー画像をタップすると、現在のセルにバインドされている情報が含まれているページに移動します。
私が欲しくて試したのは次のようなものです:
func collectionView(_ collectionView: UICollectionView, willCommitMenuWithAnimator animator: UIContextMenuInteractionCommitAnimating) {
animator.addAnimations {
self.show(PreviewViewController(image: UIImage(named: "indexpathString")), sender: self)
}
}
indexpathString
は現在選択されているセルまたはコレクションに関連しているので、それに基づいてviewControllerを初期化できます。
これを行う他の方法があるかどうか私に知らせてください。
関数 contextMenuInteraction(_:willCommitWithAnimator:)
は tableView(_:willPerformPreviewActionForMenuWith:animator:)
に置き換えられたようです。これは、表示されたメニューに関連付けられているUIContextMenuConfiguration
を提供します。メニューが表示された時点で、行を識別できる識別子を割り当てます。識別子は任意のNSCopying
オブジェクトである必要があります。 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: [])
}
}
次に、その識別子をwillPerformPreviewActionForMenuWith:animator:
関数で使用します。
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)
}
}
animator
にはpreviewViewController
というプロパティがあり、タイプは_UIViewController?
_です。これは、tableView(_:contextMenuConfigurationForRowAt:point:)
で設定したpreviewProvider
と同じであるため、previewProvider
を宛先のビューコントローラとして設定すると、次のようになります。
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
}
_
アニメータを使用して表示
_override func tableView(_ tableView: UITableView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) {
guard let destinationViewController = animator.previewViewController else { return }
animator.addAnimations {
self.show(destinationViewController, sender: self)
}
}
_