1

我的目标,同时拥有:

  • 一个处理事件的 UIButton ( .touchDown)
  • 层次结构中的另一个视图(即:super)接收touchBegan/Moved/Ended/Cancelled.

我想要那个事件,因为我需要触摸力和其他东西来进行一些计算


在upper/super 视图中,我覆盖了touchesBegan 和friends,这样我就可以获得forces 和东西。

但是,基本上, UIButton 不会转发触摸事件,因此(在此示例中)我扩展了 UIButton (在我的代码中我扩展了一个子类〜但这不会改变问题)并覆盖 touchesBegan 和朋友,并添加next?.touchesBegan(...)给它。


什么有效:

  • touchesBegan(...)正确转发到超级视图

什么不起作用:

  • touchesMoved(...)转发一次它的super观点。(即使按钮touchesMoved被调用,但next?不是nil
  • touchesEnded(...)之前调用过a 时不会调用touchesMoved(...)(如果您跟随,则只有一次 touchesMoved(...) 调用)。又next?不是nil
// One of the overrided UIButton touches event
extension UIButton {
    open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("Button: touches began - ")
        super.touchesBegan(touches, with: event)
        next?.touchesBegan(touches, with: event)
        if next == nil { print("next was nil!") }
        print("Button: touches began - end\n")
    }
}

// One of the overrided ViewController touches event
// (which is only called once for touchesMoved, and then touchesEnded not called)
extension ViewController {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("ViewController: touches began - ")
        super.touchesBegan(touches, with: event)
        print("ViewController: touches began - end\n")
    }
}

这是一个向您展示问题的示例项目

  • git clone git@bitbucket.org:5t4rrk/problemtouchmovedonlyonce.git

如果有人对为什么会出现这种行为有任何见解,请告诉我\o/

4

1 回答 1

0

我使用 a 的子类尝试了一种稍微不同的方法UIGestureRecognizer。根据您的示例项目查看下面的代码。有趣的是,UIButton 似乎正在检查.begintouchesBegan 设置的状态。可以将代码更改为不在touchesBegan方法中设置状态。看看这是否适合你。

UIKit 手势识别器还为您提供了一些委托方法和使用选择器的选项,该选择器可以访问由 touches... 方法设置的状态。但是它们并没有为您提供每次触摸的那么多信息。

资料来源:

developer.apple.com/documentation/uikit/touche developer.apple.com/documentation/uikit/uigesturer

raywenderlich.com/6747815-uigesturerecognizer-tu

代码:

class ViewController: UIViewController {
    @IBOutlet weak var button: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        button.addTarget(self, action: #selector(buttonTouched), for: .touchDown)
        
        let gesture = CustomGesture()
        self.view.addGestureRecognizer(gesture)
        self.view.isUserInteractionEnabled = true
    }
    
    @objc
    func buttonTouched(button:UIButton) {
        print("Button ACTION!")
    }
}

class CustomGesture: UIGestureRecognizer {
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesBegan(touches, with: event)
        print("ViewController: touches began")
        //  state = .began //Do not set the state to .began as this seems to be blocking the UIButton gesture.
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesMoved(touches, with: event!)
        for _ in touches {
            print("ViewController: touches moved")
        }
        state = .changed
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesEnded(touches, with: event!)
        print("ViewController: touches ended")
        state = .ended
    }
    
    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesCancelled(touches, with: event!)
        print("ViewController: touches cancelled")
        state = .cancelled
    }
}
于 2020-11-19T13:21:18.087 回答