美文网首页
自定义tabbar中间凸起位置点击处理

自定义tabbar中间凸起位置点击处理

作者: huqigu | 来源:发表于2019-01-31 18:30 被阅读13次

一、需求背景

现在很多应用都有类似下图这种UI


父视图是图中蓝色框大小,中间按钮凸起部分在视图外,在这种情况下如果我们不做任何处理,点击图中红色区域是无法被响应的。

二、介绍

响应链在这里就不过多介绍了,我们主要介绍事件分发时是如何找到最合适的事件处理者。

这里需要了解两个方法:

// 判断点击区域是否在当前视图范围内
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
// 最适合处理事件的View
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

方法一用于判断点击区域是否在当前视图范围内
方法二用于寻找最适合的View

我们以上图的例子进行说明,暂时称呼它为tabbar,其视图范围为图中1区域,中间凸起部分button在视图外的部分为2区域,两者重合部分为3区域。

在点击1、2、3区域时都会先调用tabbar的- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event,只不过返回值不同,结果不同,我们详细来看看会发生什么。

1.1、点击区域1

tabbar的方法一返回YES,接着会去遍历tabbar上所有子控件并调用子控件中的方法一,也就是会调用button的方法一,由于button不在1区域内,所以button的方法一返回NO,并且button的方法二返回null,然后调用tabbar的方法二并返回self即tabbar本身处理点击事件。


1.2、点击区域2

tabbar的方法一返回YES,接着会去遍历tabbar上所有子控件并调用子控件中的方法一,也就是会调用button的方法一,所以button的方法一返回YES,并且button的方法二返回本身,然后调用tabbar的方法二并返回button,最终由button处理点击事件。


1.3、点击区域3

我们在自定义tabbar时,一般有两种方式:
1、将自定义的tabbar添加到原来的tabbar上。
2、利用KVC替换掉原来的tabbar。

方式一
事件分发是由下往上进行分发,在调用系统tabbar方法一的时候,返回值为NO,事件不会继续向上分发,即不会调用自定义的tabbar的那两个方法,由系统的tabbar成为事件的接收者。此时无法实现我们的需求。

方式二
我们知道最终的接收者实际上是通过tabbar的方法二的返回值决定的,所以我们只需要修改自定义tabbar的方法二的实现即可。

// 其中self.plusButton为中间凸起按钮
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
     CGPoint newPoint = [self convertPoint:point toView:self.plusButton];
     // 判断是否属于按钮范围
     if ([self.plusButton pointInside:newPoint withEvent:event]) { 
         return self.plusButton;
     } else {
         return [super hitTest:point withEvent:event];
     }
}

三、总结

在做类似这种UI时,需要将自定义tabbar通过KVC替换掉原有tabbar,并重写- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event返回合适的View去处理事件。

相关文章

网友评论

      本文标题:自定义tabbar中间凸起位置点击处理

      本文链接:https://www.haomeiwen.com/subject/pggksqtx.html