iOS-自定义悬浮TabBar

最近在写一个需求,自定义TabBar,自定义TabBar一般有两种方式:

  • ① 创建一个类继承系统的UITabBar,在layoutSubviews方法中重新调整按钮的位置,再通过[self setValue:tabBar forKeyPath:@"tabBar"]方法,利用KVC设置TabBar,但是iOS 13后苹果粑粑不鼓励使用KVC;
  • ② 创建一个继承UIView的类YBTabBar,然后把系统UITabBar上的UITabBarItem移除,然后把YBTabBar加到系统TabBar的位置上;

鉴于第二种继承UIView的方式更灵活且我们的tabbar还有一种类似漂浮的效果,所以这里我选用的是第二种方式,效果如下所示:

image.png

一、TabBar实现
其实就是自定义个UIView,然后布局5个按钮,核心代码如下所示:

- (void)addTabBarButtonNorImageUrl:(NSString *)norImageUrl
                       selImageUrl:(NSString *)selImageUrl
                             title:(NSString *)title {

    // 1.创建按钮
    YBTabBarButton *tabBarBtn = [[YBTabBarButton alloc] init];
    tabBarBtn.delegate = self;
    [self addSubview:tabBarBtn];
    // 2.设置数据
    [tabBarBtn setTabBarImageUrl:norImageUrl title:title];
    // 3.监听按钮点击
    [tabBarBtn addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchDown];
    // 4.将自定义的YBTabBarButton对象
    [self.tabbarBtnArray addObject:tabBarBtn];
    [self.norImageArrM addObject:norImageUrl];
    [self.selImageArrM addObject:selImageUrl];
    // 5.默认选中第0个按钮
    if (self.tabbarBtnArray.count == 1) {
        [self buttonClick:tabBarBtn];
        [tabBarBtn.iconBtn setSelected:YES];
    }

}


- (void)layoutSubviews {
    [super layoutSubviews];

    // 按钮的frame数据
    CGFloat buttonH = self.frame.size.height;
    CGFloat buttonW = self.frame.size.width / self.tabbarBtnArray.count;
    CGFloat buttonY = 0;
    for (int index = 0; index < self.tabbarBtnArray.count; index++) {
        // 1.取出按钮
        YBTabBarButton *button = self.tabbarBtnArray[index];
        // 2.设置按钮的frame
        CGFloat buttonX = index * buttonW;
        button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
        // 3.绑定tag
        button.tag = index;
    }
}

二、再自定义一个继承系统的UITabBarController,
将系统的UITabBarItem移除,防止重影,然后将自定义UIView加到UITabBar。核心代码如下所示:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    // 初始化tabbar
    [self setupTabbar];
    // 初始化所有的子控制器
    [self setupAllChildViewControllers];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // 删除系统自动生成的UITabBarButton
    for (UIView *child in self.tabBar.subviews) {
        if ([child isKindOfClass:[UIControl class]]) {
            [child removeFromSuperview];
        }
    }
}


- (void)setupTabbar { 
    //配置信息
    YBConfig *config = [YBConfig shareInstance];
    //config.titleFont = 12;
    //config.norTitleColor = [UIColor blackColor];
    //config.selTitleColor = [UIColor cyanColor];
    //config.titleOffset = 5;
    //config.imageOffset = 10;
    //config.imageSize = CGSizeMake(50, 50);
    //config.titleHeight = 12;
    //config.bgImageOffset = 20;
    YBTabBar *customTabBar = [[YBTabBar alloc] initWithFrame:self.tabBar.bounds config:config];
    customTabBar.backgroundColor = [UIColor clearColor];
    CGRect mainFrame = customTabBar.frame;
    mainFrame.size.height = 88;
    customTabBar.frame = mainFrame;
    customTabBar.delegate = self;
    [self.tabBar addSubview:customTabBar];
    [customTabBar bringSubviewToFront:self.tabBar];
    self.customTabBar = customTabBar;
}


/**
 *  监听tabbar按钮的改变
 *  @param from   原来选中的位置
 *  @param to     最新选中的位置
 */
- (void)ybTabBar:(YBTabBar *)tabBar didSelectedButtonFrom:(NSInteger)from to:(NSInteger)to {
    self.selectedIndex = to;
    NSLog(@"----from:%ld, to:%ld ",from,to);
}

- (void)setupAllChildViewControllers {
    // 1.首页
    UIViewController *home = [[UIViewController alloc] init];
    home.view.backgroundColor = [UIColor redColor];
    [self setupChildViewController:home title:@"首页" imageName:@"shouye" selectedImageName:@"shouye_s"];
    
    // 2.消息
    UIViewController *message = [[UIViewController alloc] init];
    message.view.backgroundColor = [UIColor orangeColor];
    [self setupChildViewController:message title:@"消息" imageName:@"quanzi" selectedImageName:@"quanzi_s"];
    
    // 3.首页
    UIViewController *home1 = [[UIViewController alloc] init];
    home1.view.backgroundColor = [UIColor blueColor];
    [self setupChildViewController:home1 title:@"发现" imageName:@"shouye" selectedImageName:@"shouye_s"];
    
    // 4.消息
    UIViewController *message1 = [[UIViewController alloc] init];
    message1.view.backgroundColor = [UIColor greenColor];
    [self setupChildViewController:message1 title:@"广场" imageName:@"quanzi" selectedImageName:@"quanzi_s"];
}

/**
 *  初始化一个子控制器
 *
 *  @param childVc           需要初始化的子控制器
 *  @param title             标题
 *  @param imageName         图标
 *  @param selectedImageName 选中的图标
 */
- (void)setupChildViewController:(UIViewController *)childVc title:(NSString *)title imageName:(NSString *)imageName selectedImageName:(NSString *)selectedImageName {
    // 1.设置控制器的属性
    childVc.title = title;
    // 设置图标
    childVc.tabBarItem.image = [UIImage imageNamed:imageName];
    // 设置选中的图标
    UIImage *selectedImage = [UIImage imageNamed:selectedImageName];
    childVc.tabBarItem.selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    childVc.tabBarItem.selectedImage = selectedImage;
    
    // 2.包装一个导航控制器
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:childVc];
    [self addChildViewController:nav];
    
    // 3.添加tabbar内部的按钮
    [self.customTabBar addTabBarButtonNorImageUrl:imageName
                                      selImageUrl:selectedImageName
                                            title:title];

}

Demo下载地址

END!

你可能感兴趣的:(iOS-自定义悬浮TabBar)