在我们的项目中经常会自己自定义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(@"+++");
}
复制代码

好了 完事!

iOS自定义tabBar的更多相关文章

  1. iOS 自定义Tabbar实现push动画隐藏效果

    http://wonderffee.github.io/blog/2013/08/07/hide-custom-tab-bar-with-animation-when-push/ 在之前的一篇文章(链 ...

  2. iOS自定义TabBar使用popToRootViewControllerAnimated返回后tabbar重叠

    解决方法 所以方法就是:遵循UINavigationController的代理,用代理方法解决该Bug,代码如下: 实现代理方法: { // 删除系统自带的tabBarButton for (UIVi ...

  3. iOS 隐藏自定义tabbar

    iOS  隐藏自定义tabbar -(void)viewWillAppear:(BOOL)animated { NSArray *array=self.tabBarController.view.su ...

  4. IOS第二天-新浪微博 - 添加搜索框,弹出下拉菜单 ,代理的使用 ,HWTabBar.h(自定义TabBar)

    ********HWDiscoverViewController.m(发现) - (void)viewDidLoad { [super viewDidLoad]; // 创建搜索框对象 HWSearc ...

  5. iOS开发之功能模块--关于自定义TabBar条

    只上项目中用到的代码: 1.实现重写TabBar的TabBarItem,然后在中间额外加一个按钮. #import <UIKit/UIKit.h> @interface BikeTabBa ...

  6. iOS开发项目之四 [ 调整自定义tabbar的位置与加号按钮的位置]

    自定义tabbar与按钮的添加 01 - 把系统的tabbar用我们自己的覆盖 LHQTabBar *lhqTabBar = [[LHQTabBar alloc]init]; [self setVal ...

  7. [iOS微博项目 - 1.6] - 自定义TabBar

    A.自定义TabBar 1.需求 控制TabBar内的item的文本颜色(普通状态.被选中状态要和图标一致).背景(普通状态.被选中状态均为透明) 重新设置TabBar内的item位置,为下一步在Ta ...

  8. iOS 轻松实现自定义TabBar

    自定义TabBar的案例网上不少,昨天受到开发小伙伴的影响,尝试了一下非大神的取巧思路:Demo 1.创建RootViewController,后面创建几个继承的VC,将这几个VC添加到TabBarC ...

  9. iOS框架搭建(MVC,自定义TabBar)--微博搭建为例

    项目搭建 1.新建一个微博的项目,去掉屏幕旋转 2.设置屏幕方向-->只有竖向 3.使用代码构建UI,不使用storyboard 4.配置图标AppIcon和LaunchImage 将微博资料的 ...

随机推荐

  1. 关于微信小程序的一点经验

    2018年的11月份,自己做微信小程序相关的项目已经有四个月,这四个月自己走过很多弯路,也学到了不少经验,下面就一一总结: 一,微信小程序的radio组件是可以改变按钮样式的(比如大小,颜色等等) 改 ...

  2. python爬取疫情数据详解

    首先逐步分析每行代码的意思: 这是要引入的东西: from os import path import requests from bs4 import BeautifulSoup import js ...

  3. Spring XML Bean 定义的加载和注册

    前言 本篇文章主要介绍 Spring IoC 容器怎么加载 bean 的定义元信息. 下图是一个大致的流程图: 第一次画图,画的有点烂.

  4. 30.2 案例:ArrayList本身数据可以重复,写出去重的方法

    package day30_HashSet; /* * ArrayList特点(实现List接口) 有序.可以重复.可以使用索引 *使用ArrayList实现数据去重 * */ import java ...

  5. jsjsjs

    var TooL = {}; (function(t){ function common(){ console.log("common"); } var a = function( ...

  6. hive常用函数一

    Hive概念 Hive最适合于数据仓库应用程序,使用该应用程序进行相关静态数据分析,不需要快速响应出结果,而数据本身不会发生频繁变化. Hdfs分布式文件系统限制了hive,使其不支持记录级别的更新. ...

  7. Java课程设计之——爬虫篇

    主要使用的技术 Httplcient Jsoup 多线程 dao模式 网络爬虫简介 网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取 ...

  8. mysql优化之分区

    mysql分区类型 日常开发中我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表.这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下,如果涉及联合查询的情况,性能会 ...

  9. 学习Salesforce | Einstein业务机会评分怎么玩

    Einstein 业务机会评分(Opportunity Scoring)是销售团队的得力助手,通过分数以及研究影响分数的因素,确定业务机会的优先级,赢得更多交易. Einstein 业务机会评分可以给 ...

  10. 泛型方法或泛型类中的方法是内部调用、PInvoke 或是在 COM 导入类中定义的。

    泛型基类中引用Api函数定义时static extern,在子类中会提示: 未处理TypeLoadException 泛型方法或泛型类中的方法是内部调用.PInvoke 或是在 COM 导入类中定义的 ...