• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - 自定义 UIControl, Action 调用两次

[复制链接]
菜鸟教程小白 发表于 2022-12-12 19:23:31 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我正在尝试创建 UIControl 的子类并跟踪触摸以更改控件外观。

我不知道为什么,但是如果我从 IB 或代码添加操作(用于 .TouchUpInside),当我触摸控件时,注册操作方法会被调用两次。
堆栈跟踪告诉我,第一个调用来自 _sendActionsForEvents:withEvent:,第二个不清楚。
以下是我如何覆盖跟踪方法:

 override func continueTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool {
        let touchPoint = touch.locationInView(self)
        if CGRectContainsPoint(bounds, touchPoint) {
            sendActionsForControlEvents(.TouchDragInside)
        }
        else {
            sendActionsForControlEvents(.TouchDragOutside)
        }
        return true
    }


override func beginTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool {
    sendActionsForControlEvents(.TouchDown)
    return true
}

override func endTrackingWithTouch(touch: UITouch?, withEvent event: UIEvent?) {
    guard let tou = touch else { return }
    let touchPoint = tou.locationInView(self)
    if CGRectContainsPoint(bounds, touchPoint) {
        sendActionsForControlEvents(.TouchUpInside)
    }
    else {
        sendActionsForControlEvents(.TouchUpOutside)
    }
}

override func cancelTrackingWithEvent(event: UIEvent?) {
    sendActionsForControlEvents(.TouchCancel)
}

我也发现了这个 answer但这似乎不适合我的问题,因为当我为 .TouchUpInside 事件添加目标时,我没有从该答案中所述的事件调度程序自动获得任何操作。



Best Answer-推荐答案


我发现我误解了文档,并且可能有很多人在那里(在互联网上看到一些示例)。
覆盖上述方法并不能让您管理事件分派(dispatch),为此最好使用 sendAction:to:forEvent:
在我使用 UIControl 子类创建了一个小项目并为最流行的控件事件添加一些操作之后,这些考虑出现了:

  • 触地
  • 内部修饰
  • 在外面修饰
  • 拖到外面
  • 拖入
  • 值已更改

结果
除了值改变了,所有其他的事件都已经被调用了,甚至跟踪方法也被覆盖了。如果我们想发送一个改变的值,我们必须自己调用它,这是有道理的,因为它的名字与触摸无关。
我发现有趣的一件事是在调用外部跟踪时,当用户将手指拖动到控件边界之外大约 50% 时,它似乎被调用了,我在通过它的边界之后就期待了

class TestControl: UIControl {
    override func beginTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool {
        let touchPoint = touch.locationInView(self)
        print(touchPoint)
        return true
    }
    override func continueTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool {
        let touchPoint = touch.locationInView(self)
        print(touchPoint)

        return true
    }

    override func endTrackingWithTouch(touch: UITouch?, withEvent event: UIEvent?) {
        guard let touch = touch else { return }
        let touchPoint = touch.locationInView(self)
        print(touchPoint)

    }
}

class ViewController: UIViewController {

    @IBOutlet weak var tezst: TestControl!


    @IBAction func touchDown(sender: AnyObject){
        print("Touch Down")
    }
    @IBAction func touchUpInside(sender: AnyObject){
        print("Touch up inside")
    }

    @IBAction func touchUpOutside(sender: AnyObject){
        print("Touch up outside")
    }
    @IBAction func touchDragOutside(sender: AnyObject){
        print("Touch drag outside")
    }
    @IBAction func touchDragInside(sender: AnyObject){
        print("Touch drag inside")
    }
    @IBAction func valueChanged(sender: AnyObject){
        print("Value changed")
    }
}

关于ios - 自定义 UIControl, Action 调用两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36627846/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap