我无法弄清楚为什么在我的视图中点击文本字段和按钮不起作用。我已经检查了所有明显的事情,例如userInteractionEnabled是否设置为YES,是否安装了手势识别器,以及前景中是否有不可见的视图。
iOS中是否有最佳实践,可以在首次显示触摸时将其触摸到消耗的位置?
更新:
这两个答案都很有帮助。在我的调查过程中,我了解到如果子视图超出其父级边界,即使父级不是剪辑子视图,子视图也不会接收事件。我从文本字段中打印出了没有触及的超视图链,我看到其中一个视图的高度为0.我设置了一些约束来拉伸它,我的问题就解决了。
答案 0 :(得分:19)
您可以继承UIWindow
并覆盖-[UIWindow sendEvent]:
,然后在调用它时,使用-[UIWindow hitTest:withEvent:]
来测试哪个视图将接收该事件。
然后,您可以调用-[UIView recursiveDescription]
打印一些调试信息,以帮助您了解该视图收到触摸事件的原因。
完成后请记得致电[super sendEvent:]
。
对于那些使用Storyboard并想知道如何更改主应用程序窗口类的人:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow? = TestWindow()
// ....
}
只需提供AppDelegate
' s window
var的默认值。当应用程序启动时,UIApplicationMain
将实例化一个代理并向其询问window
。如果window
为nil
,则会自动创建新的{{1}}。但是如果我们在这里提供默认值,它将在整个应用程序中使用。
答案 1 :(得分:5)
不是问题的直接答案,但触摸消失的一个非常常见的原因是控件位于一个尺寸小于控件的uiview中,但是没有削减它的界限,所以你不会看到父视图较小(甚至可能是零大小)。
Parent UIView size=0x0, clipToBounds=false
Child UIButton size=100x50
=>儿童按钮不会获得任何触摸事件。
答案 2 :(得分:4)
您可以使用新的Xcode6实时视图调试,通过在3D中转换视图层次结构,您可以看到哪些视图高于您关注的视图并进行检查。
答案 3 :(得分:1)
我的完整 Swift 示例(来自@Bryan Chen和@kelin答案...
TableA
empid,other
1,A
1,B
1,C
TableB
empid,other
1,Y
1,Z
SELECT * FROM A INNER JOIN B ON a.empid=b.empid
答案 4 :(得分:0)
您可以使用符号断点来调试它:
-[UIWindow sendEvent:]
和po $arg3
<UITouchesEvent: 0x6000026fa6d0> timestamp: 179462 touches: {(
<UITouch: 0x7f84d6f10380> phase: Began tap count: 1 force: 0.000
window: <UIWindow: 0x7f84d6d0ad10; frame = (0 0; 375 812); autoresize = W+H;
gestureRecognizers = <NSArray: 0x600001aa8870>; layer = <UIWindowLayer: 0x6000014bd7e0>> view: <UIView: 0x7f84d6d0bff0; frame = (0 0; 375 812);
autoresize = W+H; layer = <CALayer: 0x6000014bdc60>> location in window: {165.66665649414062, 232.33332824707031} previous location in window:
{165.66665649414062, 232.33332824707031} location in view: {165.66665649414062,
232.33332824707031} previous location in view: {165.66665649414062,232.33332824707031}
)}
答案 5 :(得分:0)
查看消耗触摸事件的一种基本方法是简单地添加调试视图并覆盖hitTest(:event:)
方法。将此类附加到故事板上的视图中。
class DebugView: UIView {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let view = super.hitTest(point, with: event)
print("View")
print(view)
return view
}
}
将其附加到控制器的根视图将使您可以访问使用touch事件的视图。请注意,每次触摸事件,hitTest方法都会被调用两次。
答案 6 :(得分:0)
要从@Peter的答案中了解有关哪种姿势识别器是问题的更多详细信息,我打印出了一系列的motionRecognizer:
class TestWindow:UIWindow {
override func sendEvent(_ event: UIEvent) {
event.allTouches?.forEach() { touch in
print("touch")
print(touch.gestureRecognizers ?? "")
/// [<UILongPressGestureRecognizer: 0x7fb205964ab0; state = Possible; view = <UIView 0x7fb205964940>; target= <(action=_handleMenuGesture: ....
}
super.sendEvent(event)
}
}