如何在UITableViewCell中调用UIDocumentPickerViewController的importTapped方法
实现思路
UITableViewCell 属于视图层级,没有直接弹出控制器的能力,所有控制器的 present 操作必须由当前活跃的 UIViewController 执行。你可以通过代理协议把 cell 的点击事件传递给父控制器,再由父控制器触发文件选择器的弹出,具体实现如下:
步骤1:定义 cell 的回调协议并修改 cell 代码
// 定义代理协议,AnyObject 限制只能由类遵守,方便用weak修饰避免循环引用 protocol StickerCellDelegate: AnyObject { func cellDidTriggerImportPicker() } class LTHM_Sticker_Cell: UITableViewCell { // 声明代理属性 weak var delegate: StickerCellDelegate? @IBAction func createStickerOnTAp(_ sender: UIButton, forEvent event: UIEvent) { // 点击时通过代理通知父控制器 delegate?.cellDidTriggerImportPicker() } }
步骤2:优化原有 pickerView 类的逻辑
你原有代码里的 pickerView 本身就是 UIDocumentPickerViewController 的子类,内部又重复创建了新的 documentPicker 实例还调用 present,属于冗余逻辑,会导致弹出异常,调整后代码如下:
import MobileCoreServices // 用到kUTTypePNG需要引入这个库 class PickerView: UIDocumentPickerViewController, UIDocumentPickerDelegate { // 选择图片后的回调闭包,方便把结果回传给调用方 var onImageSelected: ((UIImage) -> Void)? init() { // 初始化时直接配置选择器参数 super.init(documentTypes: [String(kUTTypePNG)], in: .import) self.delegate = self self.allowsMultipleSelection = false self.modalPresentationStyle = .fullScreen } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { guard controller.documentPickerMode == .import, let url = urls.first, let image = UIImage(contentsOfFile: url.path) else { controller.dismiss(animated: true) return } // 把选中的图片回传 onImageSelected?(image) controller.dismiss(animated: true) } public func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) { controller.dismiss(animated: true) } }
步骤3:父控制器遵守协议并实现弹出逻辑
在你显示该 cell 的 UITableViewController / UIViewController 中实现以下代码:
// 遵守代理协议 class YourTableViewController: UITableViewController, StickerCellDelegate { override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "StickerCellID", for: indexPath) as! LTHM_Sticker_Cell // 把cell的代理设置为当前控制器 cell.delegate = self // 其他cell配置逻辑 return cell } // 实现代理方法,弹出文件选择器 func cellDidTriggerImportPicker() { let picker = PickerView() // 监听选择的图片 picker.onImageSelected = { [weak self] selectedImage in // 在这里处理选中的图片,比如更新UI、保存数据等 print("选中的图片:\(selectedImage)") } // 弹出选择器 present(picker, animated: true) } }
内容的提问来源于stack exchange,提问作者Juliette Destang
相关产品推荐
相关产品推荐

