iOS13快捷菜单轻按时如何显示或导航到当前偷看视图

flo*_*liu 8 contextmenu uitableview uicollectionview swift ios13

我正在尝试在iOS13的表格视图中实现“上下文菜单”(也尝试了集合视图,它们有相同的问题):

我按照此处的说明进行操作,创建了包含一堆照片的收藏夹视图,当进行3d触摸时,我将获得带有动作列表的预览,如下所示:

速览和菜单视图

集合视图

UITableView中的委托方法:

- (void)tableView:(UITableView *)tableView willCommitMenuWithAnimator:
(id<UIContextMenuInteractionCommitAnimating>)animator;
Run Code Online (Sandbox Code Playgroud)

并在collectionView中

- (void)collectionView:(UICollectionView *)collectionView willCommitMenuWithAnimator:
(id<UIContextMenuInteractionCommitAnimating>)animator;
Run Code Online (Sandbox Code Playgroud)

两者都没有“ indexPath”;

因此,我无法传递正在查看的当前单元格或索引。

我要实现此委托方法,因此当我点击预览图像时,它将导航到包含绑定到当前单元格的信息的预期页面。

我想要和尝试的是这样的:

func collectionView(_ collectionView: UICollectionView, willCommitMenuWithAnimator animator: UIContextMenuInteractionCommitAnimating) {
    animator.addAnimations {
        self.show(PreviewViewController(image: UIImage(named: "indexpathString")), sender: self)
    }
}
Run Code Online (Sandbox Code Playgroud)

并且indexpathString与当前选定的单元格或集合有关,因此我可以基于它初始化viewController。

请让我知道是否还有其他方法可以做到这一点。

alo*_*ili 10

在被animator调用的previewViewController中有一个属性是 type UIViewController?。这与previewProvider您在 中设置的相同tableView(_:contextMenuConfigurationForRowAt:point:),因此如果您将 设置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
}
Run Code Online (Sandbox Code Playgroud)

使用动画师来展示它

override func tableView(_ tableView: UITableView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) {
    guard let destinationViewController = animator.previewViewController else { return }

    animator.addAnimations {
        self.show(destinationViewController, sender: self)
    }
}
Run Code Online (Sandbox Code Playgroud)


And*_*net 5

该功能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: [])
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在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)
    }
}
Run Code Online (Sandbox Code Playgroud)