xcode 框架外的iOS UIButton未触发touchinside事件

gijlo24d  于 2022-11-30  发布在  iOS
关注(0)|答案(2)|浏览(145)

我有三个视图控制器和一个视图。
一个包含主视图,另一个包含自定义导航栏,第三个包含视图(也称为第三个视图控制器的子视图)。
当应用程序被加载时,导航栏视图将与子视图一起可见。在子视图中,我有一个按钮,我想放在导航栏视图的顶部。不幸的是,我不能直接使用像navigationitem.setrightbutton ...或任何其他类似的方法(所有内容都是编码的,没有nib)。
所以我所做的就是将按钮框架的y值设置为负值。这意味着按钮超出了子视图的框架边界,但它达到了我想要的效果,将按钮放置在导航栏的顶部。
遗憾的是,没有向按钮传递单击事件,因为它位于子视图框架边界之外...
我尝试过覆盖pointinside和hittest视图,但没有任何效果。
我希望我已经说清楚了。任何能解决这个问题的代码都将不胜感激。

pb3s4cty

pb3s4cty1#

触摸事件只在视图的边界内传播。尽管可以将子视图放置在其父视图的边界之外并仍然可以看到它,但事件不会传递给它。
处理事件的基础机制是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];
    }
}

相反,我建议你为自己省去很多麻烦,通过将按钮添加为导航栏的子视图来改变应用程序的工作方式,而不是使用负定位来放置它。

dzjeubhm

dzjeubhm2#

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
if yourButton.frame.contains(point) {
    let convertedPoint = yourButton.convert(point, from: self)
    return yourButton.point(inside: convertedPoint, with: event)
}
return super.point(inside: point, with: event)

}

相关问题