Swift中如何将UICollectionViewCell索引传入上下文菜单的previewProvider?
问题根因
UIContextMenuConfiguration的previewProvider参数要求接收无参数、返回UIViewController类型的函数/闭包,你修改为带Int参数的方法后,类型不匹配就会触发运行时错误。
解决方案
第一步:调整预览生成方法
给makeRatePreview增加索引参数,内部使用该索引读取大图数组的对应资源:
func makeRatePreview(cellIndex: Int) -> UIViewController { let viewController = UIViewController() // 替换为你自己的大图数组读取逻辑,这里用你的大图数组名[cellIndex]获取资源 let imageView = UIImageView(image: 你的大图数组[cellIndex]) viewController.view = imageView imageView.frame = CGRect(x: 0, y: 0, width: 100, height: 100) imageView.translatesAutoresizingMaskIntoConstraints = false imageView.contentMode = .scaleAspectFit // 建议加这个避免大图变形 viewController.preferredContentSize = imageView.frame.size return viewController }
第二步:调整上下文菜单代理实现
不要直接传入makeRatePreview方法,改用闭包包裹,捕获当前cell对应的indexPath.row传入即可:
func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { // 用闭包包裹预览生成逻辑,捕获当前indexPath.row let previewProvider: () -> UIViewController? = { [weak self] in guard let self = self else { return nil } return self.makeRatePreview(cellIndex: indexPath.row) } return UIContextMenuConfiguration(identifier: nil, previewProvider: previewProvider) { suggestedActions in let inspectAction = UIAction(title: NSLocalizedString("InspectTitle", comment: ""), image: UIImage(systemName: "arrow.up.square")) { action in // 你的查看逻辑 } let deleteAction = UIAction(title: NSLocalizedString("DeleteTitle", comment: ""), image: UIImage(systemName: "trash"), attributes: .destructive) { action in // 你的删除逻辑 } return UIMenu(title: "", children: [inspectAction, deleteAction]) } }
补充说明
- 闭包中添加
[weak self]是为了避免循环引用,如果你的大图数组是全局变量不需要访问self的话可以省略 - 可以根据你的大图实际尺寸调整
preferredContentSize,提升预览体验
内容的提问来源于stack exchange,提问作者ORStudios
相关产品推荐
相关产品推荐

