关于自定义 TabBar 新的思路及演练 (衍生的bug解决)

来源:互联网 发布:石家庄网络布线及维护 编辑:程序博客网 时间:2024/06/07 03:11

今日终极目标 中间的按钮高出 TabBar 栏
市面上的 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 还有一些实现的方法
有时间我会写个博客 再介绍给大家 ~

阅读全文
0 0
原创粉丝点击