ios - "Any?"类的 Swift3 扩展?

标签 ios swift extension-methods

更简短的解释:

您经常希望扩展“目标”...而目标通常是 Any?。但是您不能在 Any 上有扩展名。怎么做?


考虑一下,

extension UIViewController {    
    func add(tap v:UIView, _ action:Selector) {
        let t = UITapGestureRecognizer(target: self, action: action)
        v.addGestureRecognizer(t)
    }
}

太好了,你现在可以...

self.tap(redButton, #selector(clickedRedButton))

...在任何 View Controller 中。

但您几乎可以对任何目标执行相同的操作。

因此,要在 UITableViewCell 上使用扩展,您还必须拥有....

extension UIGestureRecognizerDelegate {
        func add(tap v:UIView, _ action:Selector) {
        let t = UITapGestureRecognizer(target: self, action: action)
        v.addGestureRecognizer(t)
    }
}

UITapGestureRecognizer 的目标参数实际上是 Any?

但是,你不能这样做......

extension Any { 

解决方案是什么?如何制作适用于 Any? 的扩展,例如 UITapGestureRecognizer 的第一个参数?

或者正如 Conner 的评论所暗示的那样,有没有办法:

extension  UIViewController or UIView {

而不是复制粘贴两次?

最佳答案

每个结构/类都(被动地)遵守“任何”。 Any 的扩展会将该功能添加到语言和代码中的每个类型。目前这是不可能的,我怀疑它是否会(或应该)。

无论如何,这里有几种方法可以解决这个问题。

我的偏好是添加功能的协议(protocol)扩展:

protocol TapGestureAddable {
    func addTapGestureRecognizer(to view: UIView, with action: Selector) -> UITapGestureRecognizer
}

extension TapGestureAddable {
    func addTapGestureRecognizer(to view: UIView, with action: Selector) -> UITapGestureRecognizer {
        let recognizer = UITapGestureRecognizer(target: self, action: action)
        view.addGestureRecognizer(recognizer)
        return recognizer
    }
}

extension UIViewController: TapGestureAddable { }
extension UIView: TapGestureAddable { }

这迫使您有意识地选择将功能添加到给定的类(IMO 是件好事),而不必复制任何有意义的代码。

可能更好的选择是将此逻辑改为 UIView 的扩展:

extension UIView {

    func addTapGestureRecognizer(with responder: Any, for action: Selector)  -> UITapGestureRecognizer {
        let recognizer = UITapGestureRecognizer(target: responder, action: action)
        self.addGestureRecognizer(recognizer)
        return recognizer
    }

    func addTapGestureRecognizer(with action: Selector)  -> UITapGestureRecognizer {
        let recognizer = UITapGestureRecognizer(target: self, action: action)
        self.addGestureRecognizer(recognizer)
        return recognizer
    }
}

否则,只需创建一个全局函数:

func addTapGestureRecognizer(to view: UIView, with responder: Any, for action: Selector) -> UITapGestureRecognizer {
    let recognizer = UITapGestureRecognizer(target: responder, action: action)
    view.addGestureRecognizer(recognizer)
    return recognizer
}

关于ios - "Any?"类的 Swift3 扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41641619/

相关文章:

c# - 缓存扩展方法的返回值

c# - 为什么在尝试使用动态参数调用扩展方法时出现错误 CS1973

iphone - 在 iPhone 应用程序中使用 RestKit 的最佳方式

iphone - 如何始终显示 map View 标注?

iOS swift : Downcasting AnyObject

ios - 处理存储在数组中的大图像时内存使用率高或质量好权衡

ios - 崩溃符号上传的 Xcode 错误 : symbolFileUploadLocation: The caller does not have permission

ios - 从 mp4 为 HLS 创建变体播放列表的有效方法

ios - QLPreviewController 和 TouchBegan 方法

vb.net - 如何指定 Enumerable.Count() 而不是 List.Count?