iOS自定义tabBar

作者: Hither | 来源:发表于2016-03-26 18:10 被阅读8506次

    在我们的项目中经常会自己自定义tabBar因为苹果自带的真的****太丑了****!也不满足我们的项目需求。

    好 开始行动吧!

    先上图看下我们最终实现的效果:

    继承UItabBar自定义一个自己的tabBar

    .h
    #import <UIKit/UIKit.h>
    
    @class HJTTabBar;
    @protocol ZTTabBarDelegate <UITabBarDelegate>
    
    @optional
    
    - (void)tabBarDidClickPlusButton:(HJTTabBar *)tabBar;
    
    @end
    
    @interface HJTTabBar : UITabBar
    
    @property (nonatomic, weak) id<ZTTabBarDelegate> myDelegate;
    
    @end
    
    
    .m
    #import "HJTTabBar.h"
    #import "UIBarButtonItem+Extension.h"
    #import "UIView+Extension.h"
    @interface HJTTabBar ()
    
    @property (nonatomic, weak) UIButton *plusBtn;
    
    @end
    
    @implementation HJTTabBar
    
    - (instancetype)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            UIButton *plusBtn = [[UIButton alloc] init];
            [plusBtn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button"] forState:UIControlStateNormal];
            [plusBtn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button_highlighted"] forState:UIControlStateHighlighted];
            [plusBtn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add"] forState:UIControlStateNormal];
            [plusBtn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add_highlighted"] forState:UIControlStateHighlighted];
    
            plusBtn.size = plusBtn.currentBackgroundImage.size;
            [plusBtn addTarget:self action:@selector(plusBtnClick) forControlEvents:UIControlEventTouchUpInside];
            [self addSubview:plusBtn];
            self.plusBtn = plusBtn;
        }
        return self;
    }
    
    /**
     *  加号按钮点击
     */
    - (void)plusBtnClick
    {
        // 通知代理
        if ([self.delegate respondsToSelector:@selector(tabBarDidClickPlusButton:)]) {
            [self.myDelegate tabBarDidClickPlusButton:self];
        }
    }
    
    /**
     *  想要重新排布系统控件subview的布局,推荐重写layoutSubviews,在调用父类布局后重新排布。
     */
    - (void)layoutSubviews
    {
        [super layoutSubviews];
        
        // 1.设置加号按钮的位置
        self.plusBtn.centerX = self.width*0.5;
        self.plusBtn.centerY = self.height*0.5;
        
        // 2.设置其他tabbarButton的frame
        CGFloat tabBarButtonW = self.width / 5;
        CGFloat tabBarButtonIndex = 0;
        for (UIView *child in self.subviews) {
    //UITabBarItem  UITabBarButton
            Class class = NSClassFromString(@"UITabBarItem  ");
            if ([child isKindOfClass:class]) {
                // 设置x
                child.x = tabBarButtonIndex * tabBarButtonW;
                // 设置宽度
                child.width = tabBarButtonW;
                // 增加索引
                tabBarButtonIndex++;
                if (tabBarButtonIndex == 2) {
                    tabBarButtonIndex++;
                }
            }
        }
    }
    
    @end
    
    

    下面是Category:

    UIView+Extension.h中:
    #import <UIKit/UIKit.h>
    
    @interface UIView (Extension)
    
    @property (nonatomic, assign) CGFloat x;
    @property (nonatomic, assign) CGFloat y;
    @property (nonatomic, assign) CGFloat centerX;
    @property (nonatomic, assign) CGFloat centerY;
    @property (nonatomic, assign) CGFloat width;
    @property (nonatomic, assign) CGFloat height;
    @property (nonatomic, assign) CGSize size;
    @property (nonatomic, assign) CGPoint origin;
    
    @end
    
    UIView+Extension.m中:
    #import "UIView+Extension.h"
    
    @implementation UIView (Extension)
    
    - (void)setX:(CGFloat)x
    {
        CGRect frame = self.frame;
        frame.origin.x = x;
        self.frame = frame;
    }
    
    - (void)setY:(CGFloat)y
    {
        CGRect frame = self.frame;
        frame.origin.y = y;
        self.frame = frame;
    }
    
    - (CGFloat)x
    {
        return self.frame.origin.x;
    }
    
    - (CGFloat)y
    {
        return self.frame.origin.y;
    }
    
    - (void)setCenterX:(CGFloat)centerX
    {
        CGPoint center = self.center;
        center.x = centerX;
        self.center = center;
    }
    
    - (CGFloat)centerX
    {
        return self.center.x;
    }
    
    - (void)setCenterY:(CGFloat)centerY
    {
        CGPoint center = self.center;
        center.y = centerY;
        self.center = center;
    }
    
    - (CGFloat)centerY
    {
        return self.center.y;
    }
    
    - (void)setWidth:(CGFloat)width
    {
        CGRect frame = self.frame;
        frame.size.width = width;
        self.frame = frame;
    }
    
    - (void)setHeight:(CGFloat)height
    {
        CGRect frame = self.frame;
        frame.size.height = height;
        self.frame = frame;
    }
    
    - (CGFloat)height
    {
        return self.frame.size.height;
    }
    
    - (CGFloat)width
    {
        return self.frame.size.width;
    }
    
    - (void)setSize:(CGSize)size
    {
        CGRect frame = self.frame;
        frame.size = size;
        self.frame = frame;
    }
    
    - (CGSize)size
    {
        return self.frame.size;
    }
    
    - (void)setOrigin:(CGPoint)origin
    {
        CGRect frame = self.frame;
        frame.origin = origin;
        self.frame = frame;
    }
    
    - (CGPoint)origin
    {
        return self.frame.origin;
    }
    
    @end
    
    UIBarButtonItem+Extension.h中:
    
    #import <UIKit/UIKit.h>
    
    @interface UIBarButtonItem (Extension)
    
    + (UIBarButtonItem *)itemWithTargat:(id)target action:(SEL)action image:(NSString *)image highImage:(NSString *)highImage;
    
    @end
    
    UIBarButtonItem+Extension.m中:
    
    #import "UIBarButtonItem+Extension.h"
    #import "UIView+Extension.h"
    @implementation UIBarButtonItem (Extension)
    
    /**
     *  创建一个item
     *
     *  @param target    点击item后调用哪个对象的方法
     *  @param action    点击item后调用target的哪个方法
     *  @param image     图片
     *  @param highImage 高亮的图片
     *
     *  @return 创建完的item
     */
    + (UIBarButtonItem *)itemWithTargat:(id)target action:(SEL)action image:(NSString *)image highImage:(NSString *)highImage
    {
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        // 设置图片
        [btn setBackgroundImage:[UIImage imageNamed:image] forState:UIControlStateNormal];
        [btn setBackgroundImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted];
        // 设置尺寸
        btn.size = btn.currentBackgroundImage.size;
        [btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
        
        return [[UIBarButtonItem alloc] initWithCustomView:btn];
    }
    
    @end
    
    
    

    接下来我们就该在需要的地方使用自定义的tabBar了

    • 我是在UITabBarController中使用自定义的tabBar。
    导入#import "HJTTabBar.h"并遵循 HJTTabBarDelegate协议。
    
    在- (void)viewDidLoad 中实现下面代码:
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 添加子控制器
        [self addChildVc:[[FirstPageViewController alloc] init] title:@"首页" image:@"tabbar_home" selectedImage:@"tabbar_home_selected"];
        [self addChildVc:[[CommunityViewController alloc] init] title:@"社区" image:@"tabbar_message_center" selectedImage:@"tabbar_message_center_selected"];
        [self addChildVc:[[MessageViewController alloc] init] title:@"消息" image:@"tabbar_discover" selectedImage:@"tabbar_discover_selected"];
        [self addChildVc:[[ConsultViewController alloc] init] title:@"咨询" image:@"tabbar_profile" selectedImage:@"tabbar_profile_selected"];
        
        HJTTabBar *tabBar = [[HJTTabBar alloc] init];
        
        //取消tabBar的透明效果
        tabBar.translucent = NO;
        tabBar.myDelegate = self;
        // KVC:如果要修系统的某些属性,但被设为readOnly,就是用KVC,即setValue:forKey:。
        [self setValue:tabBar forKey:@"tabBar"];
          
    }
    
    
    实现下面方法:
    
    - (void)addChildVc:(UIViewController *)childVc title:(NSString *)title image:(NSString *)image selectedImage:(NSString *)selectedImage
    {
        // 设置子控制器的文字(可以设置tabBar和navigationBar的文字)
        childVc.title = title;
        
        // 设置子控制器的tabBarItem图片
        childVc.tabBarItem.image = [UIImage imageNamed:image];
        // 禁用图片渲染
        childVc.tabBarItem.selectedImage = [[UIImage imageNamed:selectedImage] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        
        // 设置文字的样式
        [childVc.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor blackColor]} forState:UIControlStateNormal];
        [childVc.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor redColor]} forState:UIControlStateSelected];
        //    childVc.view.backgroundColor = RandomColor; // 这句代码会自动加载主页,消息,发现,我四个控制器的view,但是view要在我们用的时候去提前加载
        
        // 为子控制器包装导航控制器
        UINavigationController *navigationVc = [[UINavigationController alloc] initWithRootViewController:childVc];
        // 添加子控制器
        [self addChildViewController:navigationVc];
    }
    
    
    #pragma HJTTabBarDelegate
    /**
     *  加号按钮点击
     */
    - (void)tabBarDidClickPlusButton:(HJTTabBar *)tabBar
    {
        NSLog(@"+++");
    }
    

    好了 完事!

    相关文章

      网友评论

      • 一代骄马:你的github关了吗
        Hither:@一代骄马 没有
      • f1b498cc8499:楼主,这行代码Class class = NSClassFromString(@"UITabBarButton"); 应该换成Class class = NSClassFromString(@"UITabBarItem");吧,因为上面的四个按钮好像是Item不说barbuttton
        Hither:@晴天_5c7f 好的 谢谢了
      • 太阳和风与旅行者:如果tabbar的item是6个的话,不想显示more,全部展示出来可以吗
        Hither:@太阳和风与旅行者 自定义一个view 没有view解决不了的 如果有 那再整一个view
      • Xing_1102:我发现网上大部分自定义tabbar,在ipad上,只有两个控制的时候,会按钮的点击位置偏移,不知是何缘故,除非,移除掉所有tabbarbutton,自定义按钮不会出现问题
      • feng_dev:可以 在tabbar里面放5个tabbar item ,然后往 tabbar 里面 add subview 一个 button,这样就只需要考虑 中间按钮的位置就行了,超级简单,好像也没什么问题
        feng_dev:@我的信仰是你 最优的方法是什么啊,大神
        Hither:@伤感的小孩 :+1:
      • 天下只有一个:我想问一下,为啥我进入页面的tabbar没有默认被选中,只是点击了,才回显示选中状态
        雪_晟:我也是 后来怎么解决的呢
      • 阿兹尔:/**
        * 加号按钮点击
        */
        - (void)plusBtnClick
        {
        // 通知代理
        if (![self.delegate respondsToSelector:@selector(tabBarDidClickPlusButton:)]) {
        [self.Delegate tabBarDidClickPlusButton:self];

        }
        }
        这个按钮点击事件差 “ !” 要不 点击事件不执行
        UIButton *plusBtn = [[UIButton alloc] init];
        [plusBtn setBackgroundImage:[UIImage imageNamed:@"3-normal@2x"] forState:UIControlStateNormal];

        // [plusBtn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button_highlighted"] forState:UIControlStateHighlighted];

        // [plusBtn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add"] forState:UIControlStateNormal];

        [plusBtn setImage:[UIImage imageNamed:@"3-selected@2x"] forState:UIControlStateHighlighted];

        这里面代码不知道是不是重复了 我注释了两行 中间的图片出来了!!!初学者 不对地方 勿怪
        阿兹尔:哦 懂了! 留个qq 大神带我飞
        Hither:@阿兹尔 你注释的这两种图片分别是不同的两种图片 back是背景图 而image是那种位置在旁边的图片
      • 阿兹尔:中间的item 设置再那?能设置那种突出 图片
        Hither:@阿兹尔 这个一般都是UI给你切个这种图 切一个大点的圆 你直接放上去就行了 正式最简单的做法 如果要自己设置 就建议通过xib自定义一个tabBar 这样你想怎么搞就怎么搞
      • YYYLynn:刚运行的时候item的顺序是正确的, 点击后就变位置, 而且有一个item的title不见了~~能说一下是什么原因么??还是用这个方法还有什么需要注意的?
        Hither:@YYYLynn 原来如此
        YYYLynn:@YYYLynn 知道原因了, 我在一个item的控制器页面写了 self.title = nil; 把这句话去掉之后就好了
      • 郭鵬飛on:这个button 类别,你没有用到吧.
      • 042a0e1be73f:重写TabBar后,tabar上面的item错位,点击一次后又回恢复正常。比如说刚加载时,首页会放到最后,但是点击一次后,就会回到第一。
        韦锕爵:@iiOS 遇到同样问题,请问解决了嘛?
        042a0e1be73f:@hither 谢谢啦!
        Hither:@iiOS 不好意思 才看到 我看下 告诉你结果
      • 05928c0c7c63:有demo吗?能说下思路么,
        Hither: @樱空释的爱1 我把整个过程都写下来了啊

      本文标题:iOS自定义tabBar

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