我有三个视图控制器和一个视图。
一个包含主视图,另一个包含自定义导航栏,第三个包含视图(也就是第三个视图控制器的子视图)。
加载应用时,导航栏视图将与子视图一起显示。在子视图中,我有一个按钮,我想放在导航栏视图的顶部。不幸的是,我不能直接使用navigationitem.setrightbutton ......或任何其他类似的方法(一切都是编码,没有笔尖)。
所以我正在做的是将我的按钮框架y值设置为负值。这意味着该按钮超出了子视图的框架范围,但它实现了我想要的按钮位于导航栏顶部。
不幸的是,没有点击事件传递给按钮,因为它在子视图帧边界之外......
我已经尝试重写了pointinside和hittest视图,但没有任何工作。
我希望我已经说清楚了。任何解决此问题的代码都将非常感激。
答案 0 :(得分:2)
触摸事件仅在视图的边界内传播。虽然可以将子视图放在其父级边界之外但仍然可以看到它,但事件不会传递给它。
处理事件的基本机制是UIView的以下方法:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
此方法负责决定给定触摸事件应该转到哪个视图。当您触摸屏幕时,将调用根视图(窗口)的hitTest方法,它将在其子视图上调用该方法,并且将在其子视图上调用该方法,依此类推。
原则上你可以创建一个自定义窗口类并覆盖窗口中的hitTest方法,以强制它将事件转发到按钮,即使它超出了它的父界限,但这是非常繁琐的正确做法。它会是这样的:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
CGRect rect = WORK_OUT_WHERE_THE_BUTTON_RECT_IS_RELATIVE_TO_THE_WINDOW;
if (CGRectContainsPoint(rect, point))
{
return theButtonView;
}
else
{
return [super hitTest:point withEvent:event];
}
}
相反,我建议您通过添加按钮作为导航栏的子视图而不是使用负定位将其放置在那里来节省很多麻烦并改变应用程序的工作方式。