swift - 通过扩展实现协议(protocol)

标签 swift swift-extensions swift-protocols

<分区>

我正在尝试创建一个协议(protocol)来包装使用 UIImagePickerController 的过程,以使其在我的应用程序中更加流线型。我基本上有这样的东西:

public protocol MediaAccessor : UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func mediaCaptured(title: String, fileData: NSData, fileType: String)
}

还有一个扩展,它负责请求权限和处理委托(delegate)方法的所有繁重工作:

public extension MediaAccessor where Self : UIViewController {
    public func captureMedia() {
        //All sorts of checks for picker authorization
        let picker = UIImagePickerController()
        picker.delegate = self
        self.presentViewController(picker, animated: true, completion: nil)
    }

    func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
        //implementation of the delegate in extension
        //even though everything compiles, this method is not called on picker completion
    }
}

所以一切都可以编译,但是通过扩展实现 UIImagePickerControllerDelegate 似乎没有注册。当我显示选择器时,它允许我拍照,但 didFinishPickingImage 调用从未发生。如果我将该调用直接移动到 Controller 中,一切正常,但这样做的想法是将这些东西从 View Controller 中隐藏起来,以获得一个非常干净的界面,从而允许 Controller 从设备访问媒体。通过这样的扩展来实现协议(protocol)方法是行不通的吗?有什么我可以更改以允许它工作,而不必直接在我的 View Controller 中实现协议(protocol)吗?

最佳答案

Cocoa 是用 Objective-C 编写的。 Objective-C 看不到 Swift 协议(protocol)扩展代码。所以它不知道 imagePickerController:didFinishPickingImage: 的实现。如果你想让 Cocoa 调用一个委托(delegate)方法,你需要把它放在 Cocoa 可以看到的地方。

关于swift - 通过扩展实现协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36991867/

相关文章:

swift - 如何从 Swift 协议(protocol)返回 `[Self]`?

ios - 为什么 swift 协议(protocol)使用函数重载而不是不同名称的 func ?

swift - 我可以在协议(protocol)中有一个初始化函数吗?

Swift:作为 CGRect 的字典键

swift - 如何获取navigationBar.titleTextAttributes?在 Swift 4.0 中工作?

iOS 与 LTE 通信类似 BLE 交互

ios - 协议(protocol)实现协议(protocol)的默认实现

ios - Swift 的新手和困惑 - 在 Swift 类中存储大型常量/数据集

swift - 动态调度协议(protocol)扩展不适用于多个目标

swift - 两个不同模块中的相同类扩展