实现UIButton通过闭包添加事件

作者: _kk_ | 来源:发表于2016-11-02 15:36 被阅读471次

要实现的效果如下:

btn.addTarget(for: .touchUpInside) { (sender) in
            print("button click!")
        }

很多时候我们的的button点击事件就一行代码,而这一行代码还需要另写一个方法。然后用selector给button。这样:


Snip20161102_1.png

当代码量增大,按钮的点击事件和按钮的定义就分散在代码的不同区域,给后期的代码维护造成不便。为了解决这个问题,我给UIButton扩展了一个用尾随闭包给按钮添加事件的方法。然后代码变成这样:


Snip20161102_2.png
显然要代码集中了,也好好看了!

实现:

想法:给UIButton扩展一个方法带闭包参数的方法,在这个方法中去调用系统的addTraget方法,并把闭包保存起来,在addTraget中Selector对应的方法去执行闭包。

实现步骤:

1、在extension中给UIButton扩展一个带尾随闭包添加事件的方法:

func addTarget(for controlEvents: UIControlEvents,action:@escaping (UIButton)->())
{
}

在该方法中,要做两件事:
一、是给按钮添加响应事件,这个没啥可说的,直接调用系统API。
二、是把闭包保存起来,以便于在响应事件方法中去执行闭包。怎么保存呢,只能通过一个属性保存。extension扩展属性,用到runtime的关联属性方法。直接写一个闭包属性去保存事件闭包:


Snip20161102_3.png

写是没问题,但一运行就会错误,通过实验,发现关联对象不支持基本数据类型,和闭包类型(具体原因我也没弄清楚,等搞清楚再修改过此处)。

鉴于这种情况,定义了一个结构体,在结构体中定义了一个闭包属性。关联一个该结构体类型的对象。问题便迎刃而解。
下面是全部扩展代码:

extension UIButton{
    
    struct AssociatedClosureClass {
        var eventClosure: (UIButton)->()
    }

    private struct AssociatedKeys {
        static var eventClosureObj:AssociatedClosureClass?
    }
    
    private var eventClosureObj: AssociatedClosureClass{
        set{
            objc_setAssociatedObject(self, &AssociatedKeys.eventClosureObj, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            
        }
        get{
            return (objc_getAssociatedObject(self, &AssociatedKeys.eventClosureObj) as? AssociatedClosureClass)!
        }
    }
 
    func addTarget(for controlEvents: UIControlEvents,action:@escaping (UIButton)->()) {
        let eventObj = AssociatedClosureClass(eventClosure: action)
        eventClosureObj = eventObj
        addTarget(self, action: #selector(eventExcuate(_:)), for: controlEvents)
        
    }
    
    @objc private func eventExcuate(_ sender: UIButton){
        eventClosureObj.eventClosure(sender)
    }
}

同理,我们可以写监听通知,timer执行,segement切换的方法扩展。

如果你有更好的想法,或者能解答文中问题,希望看到你的留言。

相关文章

  • 实现UIButton通过闭包添加事件

    要实现的效果如下: 很多时候我们的的button点击事件就一行代码,而这一行代码还需要另写一个方法。然后用sele...

  • 深入理解 Scala 中的闭包(Closures)

    摘要 本文通过 Scala 语言来实现一个简单的闭包,并且通过 Opcode 来深入理解 Scala 中闭包的实现...

  • iOS开发 项目总结

    1、UIButton点击事件用block代替 添加UIButton分类,在分类中添加如下代码在.h文件中添加 在....

  • UIButton添加类别实现链式代码块

    UIButton添加类别实现链式代码块

  • 闭包

    闭包的简单说明 闭:关闭 封闭包:包住,包裹闭包:通过某种方式实现一个封闭的,包裹的,对外不公开的结构 | 空间闭...

  • nodejs复习

    [nodejs复习] 1、为什么用Nodejs,它有哪些缺点? 事件驱动,通过闭包很容易实现客户端的生命活期。 不...

  • flutter 添加点击事件

    再给组件添加点击事件时,注意引用外部变量时,无法将闭包提取为方法。下边这样写在listView添加事件会变得混乱,...

  • 控件 - UIButton(按钮)

    UIButton 即按钮,一般用于点击事件传递 初始化方法 添加事件 常用属性(方法) 通过系统头文件可以得知UI...

  • iOS UIButton 拖动事件

    UIButton 添加添加拖动事件 也可以 如果不想拖动事件和按钮点击事件冲突,可以用UIPanGestureRe...

  • 闭包的声明 实现以及调用

    1闭包的声明 闭包的实现 闭包的调用

网友评论

    本文标题:实现UIButton通过闭包添加事件

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