需求的TabBar是这样的:5个 tabItem, 中间的那个 item 部分超出系统默认TabBar的上边界。

那么实现的关键点就是如何在点击它突出的部分的时候,也可以正常获得响应。我来把问题简化,我把下图中的红色的视图(类型为RedView,继承自UIView)称为 redview,蓝色的视图(类型为BlueView,继承自UIView)称为 blueview。redview 添加在试图控制器的视图上,blueview 添加在 redview上。

在 RedView 和 BlueView 的- (UIView *)hitTest:withEvent:方法和- (void)touchesBegan:withEvent:都保持默认实现的情况下,点击 blueview 超出 redview 的部分,两个视图的- (void)touchesBegan:withEvent:均不执行。

下面我来改造一下 RedView 的- (UIView *)hitTest:withEvent:方法,如下:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *view = [super hitTest:point withEvent:event];
UIView *blueview = self.subviews.firstObject;
if (CGRectContainsPoint(blueview.frame, point)) {
return blueview;
}
return view;
}

这样重写以后,再点击上边说的那部分, RedView 的 hittesst 就会把 blueview 作为 hittest view,因此会执行到 blueview 的- (void)touchesBegan:withEvent:方法。

为什么会这样?

我们可以看一下- (UIView *)hitTest:withEvent:的说明(读原文吧,比我描述的清楚):

This method traverses the view hierarchy by calling the pointInside:withEvent: method of each subview to determine which subview should receive a touch event. If pointInside:withEvent: returns YES, then the subview’s hierarchy is similarly traversed until the frontmost view containing the specified point is found. If a view does not contain the point, its branch of the view hierarchy is ignored. You rarely need to call this method yourself, but you might override it to hide touch events from subviews.

This method ignores view objects that are hidden, that have disabled user interactions, or have an alpha level less than 0.01. This method does not take the view’s content into account when determining a hit. Thus, a view can still be returned even if the specified point is in a transparent portion of that view’s content.

Points that lie outside the receiver’s bounds are never reported as hits, even if they actually lie within one of the receiver’s subviews. This can occur if the current view’s clipsToBounds property is set to NO and the affected subview extends beyond the view’s bounds.

想要跟深入的了解这部分内容,可以阅读 Response Chain 相关的文档。这里贴上地址:https://developer.apple.com/library/content/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/event_delivery_responder_chain/event_delivery_responder_chain.html

到这里如何定义需求中的Tabbar怎么实现就很明显了。直接放个Button在中间就好了,然后调整其他四个TabItem的位置。

自定义TabBar之理解hittest的更多相关文章

  1. 1行代码为每个Controller自定义“TabBar”-b

    这篇文章大致会带你实现以下的功能,废话少说,先看东西: JPNavigationController.gif Q&A:Demo里都有那些东西? 01.关于自定义导航栏 01.第一个控制器的导航 ...

  2. 自定义tabBar

    ★★★★自定义tabBar★★★★★★★ Demo下载地址:https://github.com/marlonxlj/tabBarCustom.git 前言: 有的时候需求要对tabBar进行自定义的 ...

  3. IOS第二天-新浪微博 - 添加搜索框,弹出下拉菜单 ,代理的使用 ,HWTabBar.h(自定义TabBar)

    ********HWDiscoverViewController.m(发现) - (void)viewDidLoad { [super viewDidLoad]; // 创建搜索框对象 HWSearc ...

  4. iOS 隐藏自定义tabbar

    iOS  隐藏自定义tabbar -(void)viewWillAppear:(BOOL)animated { NSArray *array=self.tabBarController.view.su ...

  5. iOS开发之功能模块--关于自定义TabBar条

    只上项目中用到的代码: 1.实现重写TabBar的TabBarItem,然后在中间额外加一个按钮. #import <UIKit/UIKit.h> @interface BikeTabBa ...

  6. iOS开发项目之四 [ 调整自定义tabbar的位置与加号按钮的位置]

    自定义tabbar与按钮的添加 01 - 把系统的tabbar用我们自己的覆盖 LHQTabBar *lhqTabBar = [[LHQTabBar alloc]init]; [self setVal ...

  7. 关于自定义tabBar时修改系统自带tabBarItem属性造成的按钮顺序错乱的问题相关探究

      关于自定义tabBar时修改系统自带tabBarItem属性造成的按钮顺序错乱的问题相关探究 测试代码:http://git.oschina.net/Xiyue/TabBarItem_TEST 简 ...

  8. 第二篇、Swift_自定义 tabbar 的 badgeValue显示样式

    在实际的开发中,我们常常需要根据实际的需求,去改变bageValue的显示样式,默认是红色的背景,白色的字体颜色 使用方式: class BKTabBarController: UITabBarCon ...

  9. [iOS微博项目 - 1.6] - 自定义TabBar

    A.自定义TabBar 1.需求 控制TabBar内的item的文本颜色(普通状态.被选中状态要和图标一致).背景(普通状态.被选中状态均为透明) 重新设置TabBar内的item位置,为下一步在Ta ...

随机推荐

  1. java线程池的原理及实现

    1.线程池简介:     多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.         假设一个服务器完成一项任务所需时间为:T1 ...

  2. MySQL插入数据异常

    MySQL插入数据异常 1.错误如下: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:Dupli ...

  3. solaris启动过程详解

    在Sparc平台下,Solaris系统中有一个类似PC BIOS的芯片程序(EEPROM OpenBoot)负责识别分区.文 件系统和加载内核,在Solaris 2.6之后的版本中,默认的内核文件存放 ...

  4. Caused by: The Result type [json] which is defined in the Result annotation on the class

    1.错误描述 严重: Dispatcher initialization failed Unable to load configuration. - [unknown location] at co ...

  5. Django学习-21-表关系参数

    一对多关系 ForeignKey(ForeignObject) # ForeignObject(RelatedField) to, # 要进行关联的表名 to_field=None, # 要关联的表中 ...

  6. Educational Codeforces Round37 E - Connected Components?

    #include <algorithm> #include <cstdio> #include <iostream> #include <queue> ...

  7. iOS - Core Animation 核心动画

    1.UIView 动画 具体讲解见 iOS - UIView 动画 2.UIImageView 动画 具体讲解见 iOS - UIImageView 动画 3.CADisplayLink 定时器 具体 ...

  8. C#图解教程 第十七章 泛型

    泛型 什么是泛型 一个栈的示例 C#中的泛型 继续栈示例 泛型类声明泛型类创建构造类型创建变量和实例 使用泛型的栈的示例比较泛型和非泛型栈 类型参数的约束 Where子句约束类型和次序 泛型方法 声明 ...

  9. Python 学习笔记(二)开发环境的搭建

    安装Python windows 下安装: 下载地址:https://www.python.org/downloads Python的版本 3.x 是趋势 2.x 还在被大量使用 至于使用2.x 还是 ...

  10. 【转载】Spark运行架构

    1. Spark运行架构 1.1 术语定义 lApplication:Spark Application的概念和Hadoop MapReduce中的类似,指的是用户编写的Spark应用程序,包含了一个 ...