美文网首页
用block的方式为UIButton添加target

用block的方式为UIButton添加target

作者: TomatosX | 来源:发表于2017-04-03 17:23 被阅读91次

在我的项目中,我将错误提示页面的设置放在了一个类当中,方便其他页面的调用,但是这个页面有个用于重新加载的Button,我如何在其他的类为这个Button添加target呢?我想到了block的方式。接下来让我们看看如何实现。

在实现之前我们先了解一个两个方法

objc_setAssociatedObject(_:_:_:_:)objc_getAssociatedObject(_:_:)
这两个是runtime函数。对相关联的两个方法。

objc_setAssociatedObject(_:_:_:_:) 有四个参数

  • object 表示关联者,是一个对象,这里是UIButton(The source object for the association)
  • key 被关联者的索引key,所以他是唯一的(The key for the association)
  • value 被关联者,这里就是我们的block,如果这里传进来的是nil,那就表示断开关联(The value to associate with the key key for object. Pass nil to clear an existing association)
  • policy:关联策略。有五种关联策略。
    OBJC_ASSOCIATION_ASSIGN 等价于 @property(assign)
    OBJC_ASSOCIATION_RETAIN_NONATOMIC等价于 @property(strong, nonatomic)
    OBJC_ASSOCIATION_COPY_NONATOMIC等价于@property(copy, nonatomic)
    OBJC_ASSOCIATION_RETAIN等价于@property(strong,atomic)
    OBJC_ASSOCIATION_COPY等价于@property(copy, atomic)

objc_getAssociatedObject(_:_:) 就顾名思义了,就是获取被关联者。它有两个参数。

  • object 和set方法一样,表示关联者(The source object for the association)
  • key 被关联者的key(The key for the association)

我们所要做的就是将我们要传递的block关联到UIButton上去。

OK,准备完毕,接下来就是Coding的时候了。

首先,我们先来设置被关联者的key

var actionBlockKey: UInt8 = 0

声明我们的block,这个block就是我们要传进来的方法。

typealias BlockButtonActionBlock = (_ sender: UIButton) -> Void

接下来我们定义一个action的方法

class ActionBlockWrapper: NSObject {

    var block: BlockButtonActionBlock

    init(block: @escaping BlockButtonActionBlock) {
        self.block = block
    }
}

接下来就是关键的步骤,为UIButton添加扩展:

extension UIButton {

    func block_setAction(block: @escaping BlockButtonActionBlock) {
        objc_setAssociatedObject(self, &actionBlockKey, ActionBlockWrapper(block: block), objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        addTarget(self, action: #selector(UIButton.block_handleAction(sender:)), for: .touchUpInside)
    }

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

这里我们将我们传入的方法绑定到了UIButton的target上,就实现了,运用block为UIButton绑定target。我们在使用的时候,就不需要写addTarget方法,直接一个block搞定。

myButton.block_setAction { sender in
}

相关文章

网友评论

      本文标题:用block的方式为UIButton添加target

      本文链接:https://www.haomeiwen.com/subject/vfroottx.html