`touchesBegan:withEvent:` 在屏幕左边缘延迟

`touchesBegan:withEvent:` is delayed at left edge of screen

我遇到了一个问题,当您触摸屏幕的左边缘时,第一次调用 UIViewUIViewController 上的 touchesBegan:withEvent: 会延迟。这似乎是 iOS 10 的新问题,并且只发生在具有 3D Touch 的设备(iPhone 6s 和更新版本)上。事实上,如果您在常规 -> 辅助功能中禁用 3D Touch,问题就会消失。

但是,当您使用 UIGestureRecognizers 时,问题似乎没有发生。我目前的解决方法是创建一个 UIGestureRecognizer 子类来覆盖 touches* 方法并将它们转发到我的旧实现。

这只是一个错误还是有办法消除延迟?

尝试将其添加到 viewdidappear 方法中。这可能会解决问题。它也发生在我身上,但我从堆栈溢出中得到了这段代码,解决了我的问题。希望对你也有帮助

let window = view.window!
let gr0 = window.gestureRecognizers![0] as UIGestureRecognizer
let gr1 = window.gestureRecognizers![1] as UIGestureRecognizer
gr0.delaysTouchesBegan = false
gr1.delaysTouchesBegan = false

Purteeek 解决方案似乎也适用于我的情况。这是 SpriteKit 的 objective-C 实现:

- (void)didMoveToView:(SKView *)view {

    UIGestureRecognizer* gr0 = view.window.gestureRecognizers[0];
    UIGestureRecognizer* gr1 = view.window.gestureRecognizers[1];

    gr0.delaysTouchesBegan = false;
    gr1.delaysTouchesBegan = false;

}

这不会与其他手势识别器混淆,系统 3D Touch 仍然可以正常工作。我想知道为什么这不是默认行为。

我和 danialias 一样正在开发一款游戏。我找到的解决方案(目前有效,在启用了 3D Touch 的 iPhone 上进行了测试,到目前为止这是一个真正的问题..)适用于 games/apps:

UITapGestureRecognizer 似乎不受此延迟的影响,因此只需将一个添加到您的视图,并使用它来处理点击。

在我的游戏中,我存储触摸并在每次间隔更新时处理它们,所以我覆盖了

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch

然后我存储了 UITouch 实例并返回了 NO。

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    [self.touches addObject:touch];
    return NO;
}

在iOS 13.2。看来这个技巧是不可能的:

[Warning] Trying to set delaysTouchesBegan to NO on a system gate gesture
recognizer - this is unsupported and will have undesired side effects

看来唯一的解决办法是在“设置”中禁用 3D 触摸。

这对我有用

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    if let window = view.window,
        let recognizers = window.gestureRecognizers {
        recognizers.forEach { r in
            r.delaysTouchesBegan = false
            r.cancelsTouchesInView = false
            r.isEnabled = false
        }
    }
}