// 作用: 去寻找点击的View
// 点击调用: 当一个事件传递给当前View,就会调用.
// 返回值: 返回的是谁,谁就是最适合的View(就会调用最适合的View的touch方法)
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
return super.hitTest(point, with: event)
}
hitTest的底层实现:
-
先看自己是否能接受触摸事件
-
再看触摸点是否在自己身上
-
从后往前遍历子控件,拿到子控件后,再次重复1,2步骤,要把父控件上的坐标点转换为子控件坐标系下的点,再次执行hitTest方法
-
若是最后还没有找到合适的view,那么就return self,自己就是合适的view
应用实例(tabbar中间凸出按钮可以优雅的实现):
extension UITabBar {
open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if (!self.isUserInteractionEnabled || self.isHidden || self.alpha <= 0.01)
{
return nil
}
if (self.point(inside: point, with: event)) { //判断点击位置,如果是自己想点击的位置就将触摸事件传给自己
return hhl_hitTest(point: point, event: event!)
}else {
let tabBarItemWidth = ScreenW/CGFloat(self.items!.count) // 获取每个tabbarItem的宽度
let left = self.center.x - tabBarItemWidth/2;
let right = self.center.x + tabBarItemWidth/2;
if (point.x < right &&
point.x > left)
{ //当点击的point的x坐标是中间item范围内,才去修正落点
let otherPoint = CGPoint(x: point.x, y: point.y + 20) // 20为高出父视图的高度
return self.hhl_hitTest(point: otherPoint, event: event!)
}
}
return nil
}
/// 返回点击子视图位置的view
fileprivate func hhl_hitTest(point: CGPoint, event: UIEvent) -> UIView? {
for subView in self.subviews {
let convertedPoint = subView.convert(point, from: self)
let hitView = subView.hitTest(convertedPoint, with: event)
if (hitView != nil) {
return hitView
}
}
return nil
}
}
最后在中间tabBarItem添加一个扇形的对应图片即可
网友评论