欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

【iOS】自定义控件之长按按钮

程序员文章站 2022-04-15 10:49:09
【ios】自定义控件之长按按钮 需求 最近接了一个需求,长按一个按钮,需要持续的触发,手指抬起时或者离开按钮触摸区域,就结束响应。 思路 思路1:在button上添加一个长按手势。 思路2:给but...

【ios】自定义控件之长按按钮

需求

最近接了一个需求,长按一个按钮,需要持续的触发,手指抬起时或者离开按钮触摸区域,就结束响应。

思路

思路1:在button上添加一个长按手势。

思路2:给button添加一个定时器

实现

最后笔者使用了思路2的方法,采用了定时器。采用定时器最需要解决的一个问题是,定时器的关闭,于是笔者把所有能想到可以停止定时器的情况都会调用一次~

代码如下:

/// 只要手放在button上就会触发
class touchbutton: uibutton {

    fileprivate var target: anyobject?
    fileprivate var action: selector!
    fileprivate var timer: timer?
    /// 记录timer执行次数
    var count: int = 1
    /// 记录增量
    var increament: int = 1

    deinit {
        touchup()
    }

    /// 添加事件
    func addtouch(_ target: anyobject?, action: selector) {
        self.addtarget(self, action: #selector(touchdown), for: .touchdown)
        self.addtarget(self, action: #selector(touchup), for: .touchupinside)
        self.target = target
        self.action = action
    }

    /// 判断是否取消定时器,超出按钮边界时,取消定时器
    override func touchesmoved(_ touches: set, with event: uievent?) {
        let p = (touches as nsset).anyobject()
        let touch = p as! uitouch
        let point = touch.location(in: self)
        // 超出边界时,取消定时器
        if point.x < 0 || point.x > self.frame.width || point.y < 0 || point.y > self.frame.height {
            touchup()
        }
    }

    override func touchescancelled(_ touches: set, with event: uievent?) {
        touchup()
    }

    override func touchesended(_ touches: set, with event: uievent?) {
        touchup()
    }

    func touchdown() {
        self.timer?.invalidate()
        target?.perform(action)
        let timer = timer(timeinterval: 0.1, target: target!, selector: action, userinfo: nil, repeats: true)
        runloop.current.add(timer, formode: runloopmode.defaultrunloopmode)
        self.timer = timer
    }

    func touchup() {
        timer?.invalidate()
        count = 1
        increament = 1
    }
}

注意

    /// 记录timer执行次数
    var count: int = 1
    /// 记录增量
    var increament: int = 1

关于这两个字段,是因为外部需要控制其触发速率而添加的属性,你也可以根据自己的业务要求,适当的添加一些属性~