iOS自定义TabBar

自定义效果:

实现方法:

1、继承UITabBar并自定义样式

.h 文件

 
  1. #import <UIKit/UIKit.h>
  2.  
  3. @interface KYCustomTabBar : UITabBar
  4.  
  5. @end

自定义实现部分代码:

 
  1. #import "KYCustomTabBar.h"
  2.  
  3. @interface KYCustomTabBar ()
  4. /** 中间突出的item */
  5. @property (nonatomic, strong) UIButton *centerBtn;
  6. @end
  7.  
  8. @implementation KYCustomTabBar
  9. #pragma mark - Getter
  10. - (UIButton *)centerBtn {
  11.    if (!_centerBtn) {
  12.        _centerBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 80, 60)];
  13.        [_centerBtn setImage:[UIImage imageNamed:@"centerIcon"] forState:UIControlStateNormal];
  14.        [_centerBtn addTarget:self action:@selector(clickCenterBtn:) forControlEvents:UIControlEventTouchUpInside];
  15.    }
  16.    return _centerBtn;
  17. }
  18. #pragma mark - 初始化
  19. - (instancetype)initWithFrame:(CGRect)frame {
  20.    self = [super initWithFrame:frame];
  21.    if (self) {
  22.        // 设置tabBarItem选中状态时的颜色
  23.        self.tintColor = [UIColor redColor];
  24.        // 添加中间按钮到tabBar上
  25.        [self addSubview:self.centerBtn];
  26.    }
  27.    return self;
  28. }
  29.  
  30. // 重新布局tabBarItem(这里需要具体情况具体分析,本例是中间有个按钮,两边平均分配按钮)
  31. - (void)layoutSubviews {
  32.    [super layoutSubviews];
  33.    // 把tabBarButton取出来(把tabBar的SubViews打印出来就明白了)
  34.    NSMutableArray *tabBarButtonArray = [NSMutableArray array];
  35.    for (UIView *view in self.subviews) {
  36.        if ([view isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
  37.            [tabBarButtonArray addObject:view];
  38.        }
  39.    }
  40.    CGFloat barWidth = self.bounds.size.width;
  41.    CGFloat barHeight = self.bounds.size.height;
  42.    CGFloat centerBtnWidth = CGRectGetWidth(self.centerBtn.frame);
  43.    CGFloat centerBtnHeight = CGRectGetHeight(self.centerBtn.frame);
  44.    // 设置中间按钮的位置,居中,凸起一丢丢
  45.    self.centerBtn.center = CGPointMake(barWidth / 2, barHeight - centerBtnHeight/2 - 5);
  46.    // 重新布局其他tabBarItem
  47.    // 平均分配其他tabBarItem的宽度
  48.    CGFloat barItemWidth = (barWidth - centerBtnWidth) / tabBarButtonArray.count;
  49.    // 逐个布局tabBarItem,修改UITabBarButton的frame
  50.    [tabBarButtonArray enumerateObjectsUsingBlock:^(UIView *  _Nonnull view, NSUInteger idx, BOOL * _Nonnull stop) {
  51.        CGRect frame = view.frame;
  52.        if (idx >= tabBarButtonArray.count / 2) {
  53.            // 重新设置x坐标,如果排在中间按钮的右边需要加上中间按钮的宽度
  54.            frame.origin.x = idx * barItemWidth + centerBtnWidth;
  55.        } else {
  56.            frame.origin.x = idx * barItemWidth;
  57.        }
  58.        // 重新设置宽度
  59.        frame.size.width = barItemWidth;
  60.        view.frame = frame;
  61.    }];
  62.    // 把中间按钮带到视图最前面
  63.    [self bringSubviewToFront:self.centerBtn];
  64. }
  65.  
  66. #pragma mark - Actions
  67. - (void)clickCenterBtn:(UIButton *)sender {
  68.    NSLog(@"点击了中间的按钮");
  69. }
  70.  
  71. #pragma mark - UIViewGeometry
  72. // 重写hitTest方法,让超出tabBar部分也能响应事件
  73. - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
  74.    if (self.clipsToBounds || self.hidden || (self.alpha == 0.f)) {
  75.        return nil;
  76.    }
  77.    UIView *result = [super hitTest:point withEvent:event];
  78.    // 如果事件发生在tabbar里面直接返回
  79.    if (result) {
  80.        return result;
  81.    }
  82.    // 这里遍历那些超出的部分就可以了,不过这么写比较通用。
  83.    for (UIView *subview in self.subviews) {
  84.        // 把这个坐标从tabbar的坐标系转为subview的坐标系
  85.        CGPoint subPoint = [subview convertPoint:point fromView:self];
  86.        result = [subview hitTest:subPoint withEvent:event];
  87.        // 如果事件发生在subView里就返回
  88.        if (result) {
  89.            return result;
  90.        }
  91.    }
  92.    return nil;
  93. }
  94.  
  95. @end

 

2、继承UITabBarController管理多视图

    重点在下方代码14行那句话,实现自定义

 
  1. #import "KYTabBarController.h"
  2. #import "KYCustomTabBar.h"
  3.  
  4. @interface KYTabBarController ()
  5.  
  6. @end
  7.  
  8. @implementation KYTabBarController
  9.  
  10. #pragma mark - Life Cycle
  11. - (void)viewDidLoad {
  12.    [super viewDidLoad];
  13.    // 利用KVO来使用自定义的tabBar
  14.    [self setValue:[[KYCustomTabBar alloc] init] forKey:@"tabBar"];
  15.    [self addAllChildViewController];
  16. }
  17.  
  18. - (void)didReceiveMemoryWarning {
  19.    [super didReceiveMemoryWarning];
  20.    // Dispose of any resources that can be recreated.
  21. }
  22.  
  23. #pragma mark - Private Methods
  24. // 添加全部的 childViewcontroller
  25. - (void)addAllChildViewController {
  26.    UIViewController *homeVC = [[UIViewController alloc] init];
  27.    homeVC.view.backgroundColor = [UIColor redColor];
  28.    [self addChildViewController:homeVC title:@"首页" imageNamed:@"tabBar_home"];
  29.    
  30.    UIViewController *activityVC = [[UIViewController alloc] init];
  31.    activityVC.view.backgroundColor = [UIColor yellowColor];
  32.    [self addChildViewController:activityVC title:@"活动" imageNamed:@"tabBar_activity"];
  33.    
  34.    UIViewController *findVC = [[UIViewController alloc] init];
  35.    findVC.view.backgroundColor = [UIColor blueColor];
  36.    [self addChildViewController:findVC title:@"发现" imageNamed:@"tabBar_find"];
  37.    
  38.    UIViewController *mineVC = [[UIViewController alloc] init];
  39.    mineVC.view.backgroundColor = [UIColor greenColor];
  40.    [self addChildViewController:mineVC title:@"我的" imageNamed:@"tabBar_mine"];
  41. }
  42.  
  43. // 添加某个 childViewController
  44. - (void)addChildViewController:(UIViewController *)vc title:(NSString *)title imageNamed:(NSString *)imageNamed {
  45.    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
  46.    // 如果同时有navigationbar 和 tabbar的时候最好分别设置它们的title
  47.    vc.navigationItem.title = title;
  48.    nav.tabBarItem.title = title;
  49.    nav.tabBarItem.image = [UIImage imageNamed:imageNamed];
  50.    [self addChildViewController:nav];
  51. }
  52.  
  53. @end

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值