连接UIButton关闭? (斯威夫特,目标行动) [英] Hooking up UIButton to closure? (Swift, target-action)

查看:87
本文介绍了连接UIButton关闭? (斯威夫特,目标行动)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将UIButton连接到一段代码 - 从我发现的,在Swift中执行此操作的首选方法仍然是使用 addTarget(target:AnyObject?,action: Selector,forControlEvents:UIControlEvents) function。这使用 Selector 构造,可能是为了向后兼容Obj-C库。我想我理解Obj-C中 @selector 的原因 - 能够引用一个方法,因为在Obj-C方法中不是第一类值。

I want to hook up a UIButton to a piece of code – from what I have found, the preferred method to do this in Swift is still to use the addTarget(target: AnyObject?, action: Selector, forControlEvents: UIControlEvents) function. This uses the Selector construct presumably for backwards compatibility with Obj-C libraries. I think I understand the reason for @selector in Obj-C – being able to refer to a method since in Obj-C methods are not first-class values.

在Swift中,函数是一等值。有没有办法将UIButton连接到闭包,类似于:

In Swift though, functions are first-class values. Is there a way to connect a UIButton to a closure, something similar to this:

// -- Some code here that sets up an object X

let buttonForObjectX = UIButton() 

// -- configure properties here of the button in regards to object
// -- for example title

buttonForObjectX.addAction(action: {() in 

  // this button is bound to object X, so do stuff relevant to X

}, forControlEvents: UIControlEvents.TouchUpOutside)

据我所知,上述内容目前无法实现。考虑到Swift看起来像是一个非常实用的功能,为什么会这样呢?这两个选项可以明显共存,以实现向后兼容。为什么这不像JS中的onClick()?将UIButton连接到目标 - 动作对的唯一方式似乎是使用仅出于向后兼容性原因而存在的东西( Selector )。

To my knowledge, the above is currently not possible. Considering that Swift looks like it's aiming to be a quite functional, why is this? The two options could clearly co-exist for backwards compatibility. Why doesn't this work more like onClick() in JS? It seems that the only way to hook up a UIButton to a target-action pair is to use something that exists solely for backwards compatibility reasons (Selector).

我的用例是在循环中为不同的对象创建UIButtons,然后将每个对象挂钩到一个闭包。 (在字典/子类化UIButton中设置标签/查找是脏的半解决方案,但我对如何在功能上这样做感兴趣,即这种闭包方法)

My use case is to create UIButtons in a loop for different objects, and then hook each up to a closure. (Setting a tag / looking up in a dictionary / subclassing UIButton are dirty semi-solutions, but I'm interested in how to do this functionally, ie this closure approach)

推荐答案

您认为应该在库中的一般方法,但不是:写一个类别。在GitHub上有很多这个特别的,但是在Swift中找不到一个,所以我写了自己的:

The general approach for anything you think should be in the libraries but isn't: Write a category. There's lots of this particular one on GitHub but didn't find one in Swift so I wrote my own:

===把它放在自己的文件中,比如UIButton + Block.swift ===

=== Put this in its own file, like UIButton+Block.swift ===

import ObjectiveC

var ActionBlockKey: UInt8 = 0

// a type for our action block closure
typealias BlockButtonActionBlock = (sender: UIButton) -> Void

class ActionBlockWrapper : NSObject {
    var block : BlockButtonActionBlock
    init(block: BlockButtonActionBlock) {
        self.block = block
    }
}

extension UIButton {
    func block_setAction(block: BlockButtonActionBlock) {
        objc_setAssociatedObject(self, &ActionBlockKey, ActionBlockWrapper(block: block), objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        addTarget(self, action: "block_handleAction:", forControlEvents: .TouchUpInside)
    }

    func block_handleAction(sender: UIButton) {
        let wrapper = objc_getAssociatedObject(self, &ActionBlockKey) as! ActionBlockWrapper
        wrapper.block(sender: sender)
    }
}

然后像这样调用它:

myButton.block_setAction { sender in
    // if you're referencing self, use [unowned self] above to prevent
    // a retain cycle

    // your code here

}

显然,这可以改进,可以有各种事件的选项(不仅仅是内部触摸)等等。但这对我有用。
它比纯粹的ObjC版本稍微复杂一些,因为需要块的包装器。 Swift编译器不允许将块存储为AnyObject。所以我把它包起来了。

Clearly this could be improved, there could be options for the various kinds of events (not just touch up inside) and so on. But this worked for me. It's slightly more complicated than the pure ObjC version because of the need for a wrapper for the block. Swift compiler does not allow storing the block as "AnyObject". So I just wrapped it.

这篇关于连接UIButton关闭? (斯威夫特,目标行动)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆