为什么多次重复调用touchDragExit和touchDragEnter?

UIControlEventTouchDragExit

“将手指从控件内拖到其边界之外的事件”

UIControlEventTouchDragEnter

“将手指拖入控件边界的事件”

如果我模拟一个恒定的向下拖动,基本上退出控件的边界一次, 为什么touchDragExittouchDragEnter被多次调用?

触摸拖动进入退出gif

 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 } } } 

考虑手指末端的大小与像素大小的比较(特别是在Retina显示屏上)。 这种相对差异存在很大的误差空间。 操作系统必须做出一些估计,以确定你的手指在屏幕上“指向”的确切位置,当你摆动手指时,估计可能会略有改变。 因此,确定您的手指是在一个像素边界的内部还是外部可能有点困难,并且一些波动是合理的。