美文网首页IOS开发自定义tabbariOS开发
iOS开发之模仿简书App自定义TabBar详解

iOS开发之模仿简书App自定义TabBar详解

作者: naruto_yuqin | 来源:发表于2016-06-03 17:23 被阅读2723次

    先来看看效果图吧

    模仿简书自定义TabBar(纯代码).gif

    然后我们再来一步一步看看代码

    1.首先页面下面TabBar的Button需要自定义,把Button的文字放在图片下面
    //更换文字图片的位置,最主要的就是实现以下两个方法,重写父类方法
    //image ratio
    #define TabBarButtonImageRatio 0.6
    -(CGRect)imageRectForContentRect:(CGRect)contentRect
    {
        CGFloat imageW = contentRect.size.width;
        CGFloat imageH = contentRect.size.height*TabBarButtonImageRatio;
        
        return CGRectMake(0, 0, imageW, imageH);
    }
    
    -(CGRect)titleRectForContentRect:(CGRect)contentRect
    {
        CGFloat titleY = contentRect.size.height*TabBarButtonImageRatio;
        CGFloat titleW = contentRect.size.width;
        CGFloat titleH = contentRect.size.height - titleY;
        
        return CGRectMake(0, titleY, titleW, titleH);
    }
    //在头文件中增加UITabBarItem类型的属性,是为了设置图片和title比较方便
    @property(nonatomic, strong)UITabBarItem *tabBarItem;
    //实现其set方法
    - (void)setTabBarItem:(UITabBarItem *)tabBarItem
    {
        _tabBarItem = tabBarItem;
        [self setTitle:self.tabBarItem.title forState:UIControlStateNormal];
        [self setImage:self.tabBarItem.image forState:UIControlStateNormal];
        [self setImage:self.tabBarItem.selectedImage forState:UIControlStateSelected];
    }
    
    2.其次就是自定义一个TabBar,其实就是自定义个UIView
    //单独的设置写文章Button的属性,因为点击它是通过导航控制器跳转到一个在一个页面
    - (void)SetupWriteButton{
        UIButton *writeButton = [UIButton new];
        writeButton.adjustsImageWhenHighlighted = NO;
        [writeButton setBackgroundImage:[UIImage imageNamed:@"button_write~iphone"] forState:UIControlStateNormal];
        [writeButton addTarget:self action:@selector(ClickWriteButton) forControlEvents:UIControlEventTouchUpInside];
        writeButton.bounds = CGRectMake(0, 0, writeButton.currentBackgroundImage.size.width, writeButton.currentBackgroundImage.size.height);
        [self addSubview:writeButton];
        _writeButton = writeButton;
    }
    //设置自控件的frame,下面的tabbarBtnArray只添加了自定义的tabBarButton,没有加入writeButton
    //所以它的count的值是4,而subviews.count值是5;
    //因为writeButton是放在正中间,所以,在nIndex大于1时,需要再加上一个按钮的宽度btnW
    - (void)layoutSubviews{
        [super layoutSubviews];
        self.writeButton.center = CGPointMake(self.frame.size.width*0.5, self.frame.size.height*0.5);
        
        CGFloat btnY = 0;
        CGFloat btnW = self.frame.size.width/(self.subviews.count);
        CGFloat btnH = self.frame.size.height;
        
        for (int nIndex = 0; nIndex < self.tabbarBtnArray.count; nIndex++) {
            CGFloat btnX = btnW * nIndex;
            MainTabBarButton *tabBarBtn = self.tabbarBtnArray[nIndex];
            if (nIndex > 1) {
                btnX += btnW;
            }
            tabBarBtn.frame = CGRectMake(btnX, btnY, btnW, btnH);
            tabBarBtn.tag = nIndex;
        }
    }
    //这个是个公共的方法,用于添加tarBarItem
    - (void)addTabBarButtonWithTabBarItem:(UITabBarItem *)tabBarItem{
        MainTabBarButton *tabBarBtn = [[MainTabBarButton alloc] init];
        tabBarBtn.tabBarItem = tabBarItem;
        [tabBarBtn addTarget:self action:@selector(ClickTabBarButton:) forControlEvents:UIControlEventTouchDown];
        [self addSubview:tabBarBtn];
        [self.tabbarBtnArray addObject:tabBarBtn];
        
        //default selected first one
        if (self.tabbarBtnArray.count == 1) {
            [self ClickTabBarButton:tabBarBtn];
        }
    }
    //这个是通知代理,并使用一个中间变量设置按钮的选中状态,这个代理看方法名也能明白,就是为了tabBar里控制器的切换
    - (void)ClickTabBarButton:(MainTabBarButton *)tabBarBtn{
        
        if ([self.delegate respondsToSelector:@selector(tabBar:didSelectedButtonFrom:to:)]) {
            [self.delegate tabBar:self didSelectedButtonFrom:self.selectedButton.tag to:tabBarBtn.tag];
        }
        
        self.selectedButton.selected = NO;
        tabBarBtn.selected = YES;
        self.selectedButton = tabBarBtn;
    }
    
    3.再自定义一个UITabBarController,下面介绍两个比较重要的方法,如何使用自定义的tabBar
    //这个是必不可少的,功能就是把系统自带的tabBar里的按钮移除,否者会重叠
    - (void)viewWillAppear:(BOOL)animated{
        [super viewWillAppear:animated];
        
        for (UIView *child in self.tabBar.subviews) {
            if ([child isKindOfClass:[UIControl class]]) {
                [child removeFromSuperview];
            }
        }
    }
    //这个方法就是把自定义的tabBar添加到系统的tabBar上,这里的好处就是,在push或者pop控制器时,隐藏tabBar就是十分的方便
    //只要设置viewController.hidesBottomBarWhenPushed = YES;这个属性为YES就可以了。
    //如果你不是将自定义的tabBar添加到系统的tabBar上,实现起来就没这么方便了。
    - (void)SetupMainTabBar{
        MainTabBar *mainTabBar = [[MainTabBar alloc] init];
        mainTabBar.frame = self.tabBar.bounds;
        mainTabBar.delegate = self;
        [self.tabBar addSubview:mainTabBar];
        _mainTabBar = mainTabBar;
    }
    //封装一个方法来初始化子控制器
    - (void)SetupChildVc:(UIViewController *)childVc title:(NSString *)title image:(NSString *)imageName selectedImage:(NSString *)selectedImageName{
        MainNavigationController *nav = [[MainNavigationController alloc] initWithRootViewController:childVc];
        childVc.tabBarItem.image = [UIImage imageNamed:imageName];
        childVc.tabBarItem.selectedImage = [UIImage imageNamed:selectedImageName];
        childVc.tabBarItem.title = title;
        [self.mainTabBar addTabBarButtonWithTabBarItem:childVc.tabBarItem];
        [self addChildViewController:nav];
    }
    

    还以一个是自定义tabBar遇到的问题文章iOS自定义TabBar使用popToRootViewControllerAnimated重叠问题解决

    demo下载地址如下:

    demo下载地址

    相关文章

      网友评论

      • carolwhite:楼主 能加个qq吗?关于你的demo有些问题想问下。
        1是为啥要响应这个方法,不响应也有效果啊。[self.delegate respondsToSelector:@selector(tabBar:didSelectedButtonFrom:to:)]
        2.是为啥要设置2个参数,第一个感觉完全没啥用。 [self.delegate tabBar:self didSelectedButtonFrom:self.selectedButton.tag to:tabBarBtn.tag];
        naruto_yuqin:@carolwhite 不好意思,现在才看到。我的QQ是737113046。加我的时候备注一下你是简书的:blush:
      • 不会游泳的飞鱼:demo下不下来啊!
        naruto_yuqin:@Truth199834 :blush::+1:
        ab1bc6718769:@不会游泳的飞鱼 clone
        naruto_yuqin:@不会游泳的飞鱼 可以啊,我分别用两台电脑试了。

      本文标题:iOS开发之模仿简书App自定义TabBar详解

      本文链接:https://www.haomeiwen.com/subject/hqfldttx.html