父控件(UITabBar)在调用 hitTest:withEvent:方法方法时,由于触摸点不在父控件范围内,所以无法让子控件(UIButton)做为最合适的view去处理点击事件。解决方法就是,重写UITabBar的hitTest:withEvent:方法(准确的说是super调用hitTest:withEvent:,因为要实现在UITabBar添加自定义居中且超出范围的按钮都是通过自定义UITabBar的方式实现的),当无法找到这个最合适的view时,先将触摸点坐标(point参数)转换到button所在坐标系,判断触摸点是否在button范围内,如果在,则返回button为处理事件最合适的view,这样button就能正确触发点击事件,代码如下:
OC版
// 在自定义UITabBar中重写以下方法,其中self.button就是那个希望被触发点击事件的按钮
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *view = [super hitTest:point withEvent:event];
if (view == nil) {
// 转换坐标系
CGPoint newPoint = [self.button convertPoint:point fromView:self];
// 判断触摸点是否在button上
if (CGRectContainsPoint(self.button.bounds, newPoint)) {
view = self.button;
}
}
return view;
}
Swift
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
var hitView = super.hitTest(point, with: event)
if hitView == nil {
// 转换坐标系
let newPoint = deleteBtn.convert(point, from: self)
if deleteBtn.bounds.contains(newPoint) {
hitView = deleteBtn
}
}
return hitView
}