为什么 touchDragExit 和 touchDragEnter 被多次重复调用? [英] Why are touchDragExit and touchDragEnter being called repetitively multiple times?

查看:25
本文介绍了为什么 touchDragExit 和 touchDragEnter 被多次重复调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

导入 UIKit类视图控制器:UIViewController {覆盖 func viewDidLoad() {super.viewDidLoad()让 btn = CustomButton(frame: CGRect(x: 100, y: 100, width: 100, height: 100), image:UIImage())btn.setTitle("", for: .normal)btn.backgroundColor = UIColor.greenself.view.addSubview(btn)}}类自定义按钮:UIButton {初始化(框架:CGRect,图像:UIImage?){super.init(框架:框架)self.addTargets()}需要初始化?(编码器aDecoder:NSCoder){super.init(编码器:aDecoder)}私有函数 addTargets() {self.addTarget(self, action: #selector(self.touchDown), for: UIControlEvents.touchDown)self.addTarget(self, action: #selector(self.touchUpInside), for: UIControlEvents.touchUpInside)self.addTarget(self, action: #selector(self.touchDragExit), for: UIControlEvents.touchDragExit)self.addTarget(self, action: #selector(self.touchDragEnter), for: UIControlEvents.touchDragEnter)self.addTarget(self, action: #selector(self.touchCancel), for: UIControlEvents.touchCancel)}功能触摸向下(){打印(触地")UIView.animate(withDuration: 0.05, 动画: {self.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)},完成:无)}func touchUpInside() {打印(修饰内部")UIView.animate(withDuration: 0.7, delay: 0.0, usingSpringWithDamping: 0.2, initialSpringVelocity: 9.0, options: [.curveEaseInOut, .allowUserInteraction], 动画: {self.transform = CGAffineTransform.identity},完成:无)}func touchDragExit() {打印(触摸拖动退出")UIView.animate(withDuration: 0.7, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 0.0, options: [.curveEaseInOut], animations: {self.transform = CGAffineTransform.identity},完成:无)}func touchDragEnter() {打印(触摸拖动进入")UIView.animate(withDuration: 0.05, 动画: {self.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)},完成:无)}功能触摸取消(){打印(触摸取消")UIView.animate(withDuration: 0.05) {self.transform = CGAffineTransform.identity}}}

解决方案

将手指末端的大小与像素大小(尤其是在 Retina 显示屏上)进行比较.这种相对差异存在很大的误差空间.操作系统必须进行一些估计才能准确地确定您的手指在屏幕上指向"的位置,并且当您摆动手指时,估计可能会略有变化.因此,确定您的手指是在一个像素边界的内部还是外部可能有点困难,但有些波动是合理的.

UIControlEventTouchDragExit is

"an event where a finger is dragged from within a control to outside its bounds"

UIControlEventTouchDragEnter is

"an event where a finger is dragged into the bounds of the control"

If I simulate a constant drag down, essentially exiting the bounds of the control once, why are touchDragExit and touchDragEnter being called multiple times?

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let btn = CustomButton(frame: CGRect(x: 100, y: 100, width: 100, height: 100), image:UIImage())
        btn.setTitle("", for: .normal)
        btn.backgroundColor = UIColor.green
        self.view.addSubview(btn)
    }
}

class CustomButton: UIButton {

    init(frame: CGRect, image:UIImage?) {
        super.init(frame: frame)
        self.addTargets()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    private func addTargets() {
        self.addTarget(self, action: #selector(self.touchDown), for: UIControlEvents.touchDown)
        self.addTarget(self, action: #selector(self.touchUpInside), for: UIControlEvents.touchUpInside)
        self.addTarget(self, action: #selector(self.touchDragExit), for: UIControlEvents.touchDragExit)
        self.addTarget(self, action: #selector(self.touchDragEnter), for: UIControlEvents.touchDragEnter)
        self.addTarget(self, action: #selector(self.touchCancel), for: UIControlEvents.touchCancel)
    }

    func touchDown() {
        print("touched down")
        UIView.animate(withDuration: 0.05, animations: {
            self.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
        },completion: nil)
    }

    func touchUpInside() {
        print("touch up inside")
        UIView.animate(withDuration: 0.7, delay: 0.0, usingSpringWithDamping: 0.2, initialSpringVelocity: 9.0, options: [.curveEaseInOut, .allowUserInteraction], animations: {
            self.transform = CGAffineTransform.identity

        }, completion: nil)
    }

    func touchDragExit() {
        print("touch drag exit")
        UIView.animate(withDuration: 0.7, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 0.0, options: [.curveEaseInOut], animations: {
            self.transform = CGAffineTransform.identity

        }, completion: nil)

    }

    func touchDragEnter() {
        print("touch drag enter")
        UIView.animate(withDuration: 0.05, animations: {
            self.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
        },completion: nil)
    }

    func touchCancel() {
        print("touch canceled")
        UIView.animate(withDuration: 0.05) {
            self.transform = CGAffineTransform.identity
        }
    }

}

解决方案

Consider the size of the end of your finger compared to the size of a pixel (particularly on a Retina display). There's a lot of room for error in that relative difference. The OS has to make some estimations to figure out exactly where your finger is "pointing" on the screen and as you wiggle your finger that estimation might change slightly. As a result figuring out whether your finger is inside or outside of a one pixel boundary can be a bit tough and some fluctuation is reasonable.

这篇关于为什么 touchDragExit 和 touchDragEnter 被多次重复调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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