You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 09:24:02