市面上的 App 有各种样式的 TabBar
有最基本的 这样的
也有进阶一点的
这样的 TabBar 我们用 LayoutSubView 就能够实现
今天带来一种不同的思路 与大家分享
新建项目 AppDelegate.m 中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
_window = [[UIWindow alloc] init];
_window.backgroundColor = [UIColor whiteColor];
_window.rootViewController = [[MainViewController alloc] init];
[_window makeKeyAndVisible];
return YES;
}
我们新建一个类 MainViewController 继承与 UITabBarController
来到 MainViewController.m 中
创建最基本的4个 TabBar
- (void)viewDidLoad {
[super viewDidLoad];
[self setupUI];
}
- (void)setupUI {
for (NSInteger i = 0; i < 5; i++) {
UIViewController *vC = [[UIViewController alloc] init];
vC.title = @(i).description;
[self addChildViewController:vC];
}
}
效果如下:
我们的目标呢 是在”2”这个位置放一个 button
先实例化一个 button
UIButton *btn = [[UIButton alloc] init];
获取 TabBar 的 bounds 和每个 button 的宽度
CGRect rect = self.tabBar.bounds;
CGFloat w = rect.size.width / 5;
设置 button 的颜色和 frame 并添加到控制器
这里使用 CGRectInset
给定一个矩形 中心点不变 正值是内聚 负值是外扩
btn.backgroundColor = [UIColor redColor];
btn.frame = CGRectInset(rect, 0, 0);
[self.tabBar addSubview:btn];
运行程序我们会看到红色的 button 已经把整个 TabBar 都盖住了
我们想要的效果是 红色的button 只占 TabBar 的 1/5 并且居中
此时我们对 button 的 frame 进行修改
btn.frame = CGRectInset(rect, 2 * w, 0);
看一下修改后的效果 ��
至此 与懂球帝和微博类似的效果就实现了
那之前我们定的目标 红色的 button 更高大一点是如何实现的呢?
其实也很简单 我们只要修改刚才代码的 y 值就可以轻松实现
btn.frame = CGRectInset(rect, 2 * w, -10);
剩下的我们只需要把 UI设计师给我们提供的图片往 button 上一放
一个美丽的 TabBar 就这么出来啦 !
但是得注意 用户在点击 超过 TabBar 部分的 button 时是无法响应的
因为它已经超过父视图的范围 所以无法接受监听
并且 只做这样的设置 用户在多次点击”1”和”3”的边缘时会出现一些 bug
如图�� :
这样的 bug 着实也是吓我一跳
为什么会出现这样诡异的 bug 呢?
我们运行程序 看一下视图层次
通过视图层次 我们清楚的看见 每一个 TabBar button 之间都会有间隙
这个间隙 是苹果为了方便用户 做了一个容错的处理 使每个中间都有一个间隙
这个间隙轻易还点击不出来 ��
但是如果我们的项目上线了,什么样 bug 都能被用户发现出来
他们在真机中 很轻易的就能够将这个 bug 点击出来
这样的方法虽然比 LayoutSubView 简单 但是有个 bug
这要如何解决呢 ?
我们跳到 UITabBarController 的头文件中
发现里面有个代理方法
46| @property(nullable, nonatomic,weak) id<UITabBarControllerDelegate> delegate;
在这个代理方法中 我们看到一个方法
52| - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController NS_AVAILABLE_IOS(3_0);
shouldSelect 是否应该被选中
回到 HMMainViewController.m 中
设置代理 遵守协议
@interface HMMainViewController () <UITabBarControllerDelegate>
self.delegate = self;
我们刚才在头文件中看见的方法 粘进项目中
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
return ![viewController isMemberOfClass:[UIViewController class]];
}
这个方法返回的是 BOOL 类型
我们返回一下这行代码就可以解决间隙问题 ~
再点击 就点击不到那个间隙了
类似懂球帝 微博这样的 TabBar 还有一些实现的方法
有时间我会写个博客 再介绍给大家 ~