【问题标题】:iOS touchesMoved forwarded only once by UIButtoniOS touchesMoved 仅由 UIButton 转发一次
【发布时间】:2021-03-02 16:24:01
【问题描述】:

我的目标,同时拥有:

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

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


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

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


什么有效:

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

什么不起作用:

  • touchesMoved(...)转发一次 到其super 视图。 (即使按钮的touchesMoved 被调用并且next? 不是nil
  • touchesEnded(...)NOT CALLED,当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")
    }
}

Here is an example project to show you the problem:

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

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

【问题讨论】:

    标签: ios swift uibutton touchesmoved touchesended


    【解决方案1】:

    我使用UIGestureRecognizer 的子类尝试了一种稍微不同的方法。根据您的示例项目查看下面的代码。有趣的是,UIButton 似乎正在检查 touchesBegan 设置的状态.begin。可以将您的代码更改为不在 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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-19
      相关资源
      最近更新 更多