我有一个可在iPhone和iPad上运行的应用程序,并使用了UISplitViewController,我将其折叠在iPhone上,并使用导航项在“主视图”和“细节”视图控制器之间移动。在detailViewController上,我有一个大的正方形视图,覆盖了iPhone的宽度,减去了一些边距。该视图接收touchesBegan,tackedEnded,tap,doubleTap和longTap事件,供在应用程序中使用。
最近,在执行一些UITest代码时,我发现在iPhone 6 Plus模拟器的屏幕左侧附近出现了不必要的touchedEnded事件。后来我发现,在iPhone 8 Plus和iPhone XR上,我没有得到touchesBegan或touchesEnded事件。超出显示屏的第40点,一切正常。然后,我发现2x设备在10pt之前有此问题,但是大部分被我的边缘余量吸收了。 iPad即使在纵向折叠模式下也完全没有此问题。
我解构了我的App,发现它在我使用SplitViewController时发生。然后,我在一个测试用例中重新创建了问题,在该用例中,我创建了一个Master-Detail App,并将视图添加到detailViewController视图,并将其命名为GameInputView,然后添加了以下文件:
//
// GameInputView.swift
import UIKit
private var debug:String? = String()
class GameInputView:UIView {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
self.isExclusiveTouch = true
let tapRecognizer1 = UILongPressGestureRecognizer(target: self, action:#selector(gameboardPressed(_:)))
tapRecognizer1.numberOfTouchesRequired = 1
self.addGestureRecognizer(tapRecognizer1)
let tapRecognizer2 = UITapGestureRecognizer(target: self, action:#selector(gameboardDoubleTapped(_:)))
tapRecognizer2.require(toFail: tapRecognizer1)
tapRecognizer2.numberOfTapsRequired = 2
self.addGestureRecognizer(tapRecognizer2)
let tapRecognizer3 = UITapGestureRecognizer(target: self, action:#selector(gameboardTapped(_:)))
tapRecognizer3.numberOfTapsRequired = 1
tapRecognizer3.require(toFail: tapRecognizer2)
self.addGestureRecognizer(tapRecognizer3)
}
var locationSave:CGPoint = CGPoint.zero
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
print(" device = \(deviceName), scale = \(UIScreen.main.scale)")
guard let touch = touches.first else { return }
locationSave = touch.location(in: self)
print("gameBoard touchesBegan, location \(locationSave)")
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
print(" Unwanted gameBoard touchesEnded!")
//assert(UIScreen.main.scale == 3.0,"touchEnded is never called unless scale is 3.0")
//assert(false,"touchEnded should never called")
}
@objc func gameboardTapped(_ gesture: UITapGestureRecognizer) {
print(" GameBoard Tapped Action")
let location = gesture.location(in: self)
//assert(location == locationSave, "touch and tap don't agree on location")
}
@objc func gameboardDoubleTapped(_ gesture: UITapGestureRecognizer) {
print("\n GameBoard Double Tapped Action")
}
@objc func gameboardPressed(_ gesture: UITapGestureRecognizer) {
print("\n GameBoard Long Press Action")
if gesture.state == .began {
} else if gesture.state == .ended {
}
}
}
您可以自己测试一下。
我向苹果提交了一份故障报告,并认为我可以在不需要的touchedEnded周围进行编码,直到发现我也丢失了touchedBegan为止。
因此,作为最后的手段,我试图找到并销毁SplitViewController PanGestureRecognizer。我做的第一件事是为SplitViewController创建一个伴随的swift文件,以便我可以检查其view.recognizers等。我将presentWithGesture设置为false,但没有帮助。我设置view.recognizers = nil或[],没有帮助。设置view.gestureRecognizers!.first!.isEnabled = false,没有帮助。
最后,我添加了一个UISplitViewControllerDelegate,它解决了这个问题,但是我只得到了detailViewController,无法导航回到masterViewController。 UISplitViewControllerDelegate中的所有方法都是可选的,因此当我说我创建一个委托时,我的意思是一个空的委托,只需将协议添加到类定义中并设置委托= self即可,它改变了SplitViewController的功能。因此,现在我有了一系列方法的半无限排列,可以使用这些方法来恢复功能,同时仍保持触摸事件。
问题是,是否有人找到解决方法以使触摸事件正常工作?
iPhone XR的左边缘现在对我已经死了。