ios - 使用扩展创建可点击的 UIImageView

标签 ios swift uiimageview clickable swift-extensions

我有以下 Swift 代码。

extension UIImageView {
    func enableClickablePrint() {
        let imageTap = UITapGestureRecognizer(target: self, action: #selector(imageTapped))
        self.addGestureRecognizer(imageTap)
        self.isUserInteractionEnabled = true
    }
    func disableClickablePrint() {
        // HERE
    }
    func toggleClickablePrint() {
        // HERE
    }

    @objc fileprivate func imageTapped(_ sender: UITapGestureRecognizer) {
        print("Image tapped")
    }
}

我遇到的问题是如何填写 disableClickablePrinttoggleClickablePrint 函数。

我希望能够执行以下操作。

extension UIImageView {
    var imageTap: UITapGestureRecognizer?
    func enableClickablePrint() {
        imageTap = UITapGestureRecognizer(target: self, action: #selector(imageTapped))
        self.addGestureRecognizer(imageTap)
        self.isUserInteractionEnabled = true
    }
    func disableClickablePrint() {
        if let theImageTap = imageTap {
            self.removeGestureRecognizer(theImageTap)
            imageTap = nil
        }
    }
    func toggleClickablePrint() {
        if let theImageTap = imageTap {
            disableClickablePrint()
        } else {
            enableClickablePrint()
        }
    }

    @objc fileprivate func imageTapped(_ sender: UITapGestureRecognizer) {
        print("Image tapped")
    }
}

当然,问题是您不能像我想的那样在扩展中存储属性。

无论如何要实现这个目标?我想尽可能保持干净,除非绝对必要,否则不要使用花哨的技巧。

正确的做法是将其转换为 UIImageView 的子类吗?如果可能的话,我想尽量避免这种情况,因为如果我想把它变成一个框架或库之类的东西,子类就不能很好地集成到界面构建器中,开发人员将不得不添加额外的步骤来改变他们所有 ImageView 的类。如果可能的话,我认为最好避免这种情况。

最佳答案

您的问题是您需要能够识别您添加的UIGestureRecognizer,但您不能将其存储在属性中。

这是一个(经过测试的)解决方案,它对 UITapGestureRecognizer 进行子类化,使 UIGestureRecognizer 可识别,然后使用 first( where:) 查看是否添加了:

extension UIImageView {

    class _CFTapGestureRecognizer : UITapGestureRecognizer { }

    private var _imageTap: _CFTapGestureRecognizer? { return self.gestureRecognizers?.first(where: { $0 is _CFTapGestureRecognizer }) as? _CFTapGestureRecognizer }

    func enableClickablePrint() {
        // Only enable once
        if _imageTap == nil {
            let imageTap = _CFTapGestureRecognizer(target: self, action: #selector(imageTapped))
            self.addGestureRecognizer(imageTap)
            self.isUserInteractionEnabled = true
        }
    }

    func disableClickablePrint() {
        if let theImageTap = _imageTap {
            self.removeGestureRecognizer(theImageTap)
        }
    }

    func toggleClickablePrint() {
        if _imageTap == nil {
            enableClickablePrint()
        } else {
            disableClickablePrint()
        }
    }

    @objc fileprivate func imageTapped(_ sender: UITapGestureRecognizer) {
        print("Image tapped")
    }
}

关于ios - 使用扩展创建可点击的 UIImageView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51911658/

相关文章:

ios - 个人 pem 文件和标准 pem 文件有什么区别?

swift - 遍历 Collection View 中的所有单元格,可见与否

ios - swift indexPath.row==0 对 UITableViewCell 的工作很奇怪

ios - 将自定义 UIView 更改为 UIScrollView

iphone - 引用计数的对象在释放后使用

ios - 从 subview 调用 UIView.animate 不起作用

iphone - 我需要在仪器上测试我的应用程序吗?

ios - XCODE 错误 : "...the field reciever doesn' t exist in your schema (Code: 102, 版本 : 1. 7.5)。”

ios - 如何从 subView 开始获取 ViewController 实例

iphone - 在 iPhone 上运行我的应用程序时图像模糊