作为iOS开发最常用的两个多视图控制器 NavigationController 和 TabBarController 已经很强大了,基本上在大部分的应用中都能看到它们的影子。但是在使用的过程中,系统自带的空间也经常不能满足我们的需求,所以经常需要使用自定义来实现功能。

之前写过自定义NavigationBar:  http://www.cnblogs.com/code-cd/p/4801661.html  。今天大概写一下自定义TabBar。如有不足之处,还请多多指正。

一、创建TabBarContoller

创建 CDTabBarController,CDRedViewController,CDGreenViewController

在AppDelegate.m中,设置创建TabBarController,并设置根视图为TabBarController

//
// AppDelegate.m
// ComstomTabBar
//
// Created by lcd on 15/9/15.
// Copyright © 2015年 lcd. All rights reserved.
// #import "AppDelegate.h"
#import "CDTabBarController.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CDTabBarController *tabBarController = [[CDTabBarController alloc] init];
self.window.rootViewController = tabBarController;
return YES;
}

添加子视图

在CDTabBarController.m中

//
// CDTabBarController.m
// ComstomTabBar
//
// Created by lcd on 15/9/15.
// Copyright © 2015年 lcd. All rights reserved.
// #import "CDTabBarController.h"
#import "CDRedViewController.h"
#import "CDGreenViewController.h" @interface CDTabBarController () @end @implementation CDTabBarController - (void)viewDidLoad {
[super viewDidLoad];
//设置子视图
[self setupChildControllers]; }
//这里设置两个视图控制器的代码是重复的,为了便于观察理解,我没有抽取,大家日常写代码的时候请注意养成良好的代码习惯。
- (void)setupChildControllers {
CDRedViewController *redViewController = [[CDRedViewController alloc] init];
redViewController.view.backgroundColor = [UIColor redColor];
redViewController.tabBarItem.title = @"red";
//设置图片
redViewController.tabBarItem.image = [UIImage imageNamed:@"tabbar_mainframe"];
//设置选中图片
redViewController.tabBarItem.selectedImage = [UIImage imageNamed:@"tabbar_mainframeHL"]; CDGreenViewController *greenViewController = [[CDGreenViewController alloc] init];
greenViewController.view.backgroundColor = [UIColor greenColor];
greenViewController.tabBarItem.title = @"green";
greenViewController.tabBarItem.image = [UIImage imageNamed:@"tabbar_me"];
greenViewController.tabBarItem.selectedImage = [UIImage imageNamed:@"tabbar_meHL"];
self.viewControllers = @[redViewController,greenViewController];
}

这样两个子视图已经添加进TabBarViewController了。如图:

但是这里有个问题。,我设置的选中图片 是绿色的,这里显示的却是蓝色的。

这是因为在ios7之后,苹果默认会把UITabBar上面的按钮图片渲染成蓝色。如果要显示自己需要的颜色可以通过以下方法:

    UIImage *selectedImage = [[UIImage imageNamed:@"tabbar_mainframeHL"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
redViewController.tabBarItem.selectedImage = selectedImage;

二、自定义TabBar

自定义TabBar有几种不同的方式,难易程度不同,效果也不尽相同

1.修改TabBar字体

方法1:

在CDRedViewController.m中

NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:11.0],
NSBackgroundColorAttributeName:[UIColor cyanColor]};
[self.tabBarItem setTitleTextAttributes:dic forState:UIControlStateNormal];

方法二:

在CDTabBarController.m中

- (instancetype)init
{
self = [super init];
if (self) {
[self setTabBarItem:self.tabBarItem Title:@"title" withTitleSize:17.0 andFoneName:@"Marion-Italic" selectedImage:selectedImage withTitleColor:[UIColor redColor] unselectedImage:unselectedImage withTitleColor:[UIColor blueColor]];
}
return self;
} - (void)setTabBarItem:(UITabBarItem *)tabbarItem
Title:(NSString *)title
withTitleSize:(CGFloat)size
andFoneName:(NSString *)foneName
selectedImage:(NSString *)selectedImage
withTitleColor:(UIColor *)selectColor
unselectedImage:(NSString *)unselectedImage
withTitleColor:(UIColor *)unselectColor{ //设置图片
tabbarItem = [tabbarItem initWithTitle:title image:[[UIImage imageNamed:unselectedImage]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] selectedImage:[[UIImage imageNamed:selectedImage]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]]; //未选中字体颜色
[[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:unselectColor,NSFontAttributeName:[UIFont fontWithName:foneName size:size]} forState:UIControlStateNormal]; //选中字体颜色
[[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:selectColor,NSFontAttributeName:[UIFont fontWithName:foneName size:size]} forState:UIControlStateSelected];
}

  这种方法可以修改TabBar字体大小。但是其本质还是系统自带的TabBar。离我们的目标:真正的自定义TabBar还有距离

2.这种方法是之前查到的一种,用过一次,感觉不是很好用,贴上代码,有兴趣的可以了解一下,没兴趣的建议直接看第三种

- (UIButton *)plusButton
{
if (_plusButton == nil) { UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add"] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:@"tabbar_compose_background_icon_add"] forState:UIControlStateHighlighted];
[btn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button_highlighted"] forState:UIControlStateHighlighted]; // 默认按钮的尺寸跟背景图片一样大
// sizeToFit:默认会根据按钮的背景图片或者image和文字计算出按钮的最合适的尺寸
[btn sizeToFit]; _plusButton = btn; [self addSubview:_plusButton]; }
return _plusButton;
} // self.items UITabBarItem模型,有多少个子控制器就有多少个UITabBarItem模型
// 调整子控件的位置
- (void)layoutSubviews
{
[super layoutSubviews]; CGFloat w = self.bounds.size.width;
CGFloat h = self.bounds.size.height; CGFloat btnX = 0;
CGFloat btnY = 0;
CGFloat btnW = w / (self.items.count + 1);
CGFloat btnH = self.bounds.size.height; int i = 0;
// 调整系统自带的tabBar上的按钮位置
for (UIView *tabBarButton in self.subviews) {
// 判断下是否是UITabBarButton
if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton" )]) {
if (i == 2) {
i = 3;
}
btnX = i * btnW; tabBarButton.frame = CGRectMake(btnX, btnY, btnW, btnH); i++;
} } // 设置添加按钮的位置
self.plusButton.center = CGPointMake(w * 0.5, h * 0.5); }

3.这种方法的思路是,先把自带的TabBar取消,然后自定义View,add到TabBar的位置代替TabBar。然后在自定义View上添加button,设置button点击时间,改变selectIndex,关联各个子viewController,覆盖相关事件。

  新建CDTabBarButton.h  & CDTabBarButton.m
 在CDTabBarButton.m中
//注释掉[super setHighlighted:highlighted] 即可以取消点击时的高亮状态
- (void)setHighlighted:(BOOL)highlighted{
// [super setHighlighted:highlighted];
}

  CDTabBarController.h

//
// CDTabBarController.h
// ComstomTabBar
//
// Created by lcd on 15/9/15.
// Copyright © 2015年 lcd. All rights reserved.
// #import <UIKit/UIKit.h> @interface CDTabBarController : UITabBarController @end

  

  CDTabBarController.m

//
// CDTabBarController.m
// ComstomTabBar
//
// Created by lcd on 15/9/15.
// Copyright © 2015年 lcd. All rights reserved.
// #import "CDTabBarController.h"
#import "CDRedViewController.h"
#import "CDGreenViewController.h"
#import "CDTabBarButton.h" @interface CDTabBarController ()
/**
* 设置之前选中的按钮
*/
@property (nonatomic, weak) UIButton *selectedBtn;
@end @implementation CDTabBarController - (void)viewDidLoad {
[super viewDidLoad];
//设置子视图
[self setupChildControllers]; //设置TabBar
[self setupTabBar]; } - (void)setupChildControllers {
CDRedViewController *redViewController = [[CDRedViewController alloc] init];
redViewController.view.backgroundColor = [UIColor redColor];
redViewController.tabBarItem.title = @"red";
//设置图片
redViewController.tabBarItem.image = [UIImage imageNamed:@"tabbar_mainframe"];
//设置选中图片
redViewController.tabBarItem.selectedImage = [UIImage imageNamed:@"tabbar_mainframeHL"]; CDGreenViewController *greenViewController = [[CDGreenViewController alloc] init];
greenViewController.view.backgroundColor = [UIColor greenColor];
greenViewController.tabBarItem.title = @"green";
greenViewController.tabBarItem.image = [UIImage imageNamed:@"tabbar_me"];
greenViewController.tabBarItem.selectedImage = [UIImage imageNamed:@"tabbar_meHL"];
self.viewControllers = @[redViewController,greenViewController];
} - (void)setupTabBar {
//删除现有的tabBar
CGRect rect = self.tabBar.frame;
[self.tabBar removeFromSuperview]; //移除TabBarController自带的下部的条 UIView *myView = [[UIView alloc] init];
myView.frame = rect;
myView.backgroundColor = [UIColor cyanColor];
[self.view addSubview:myView]; for (int i = 0; i < 2; i++) { CDTabBarButton *button = [[CDTabBarButton alloc] init]; NSString *imageName = [NSString stringWithFormat:@"tabbar_%d",i];
NSString *imageNameSel = [NSString stringWithFormat:@"tabbar_%dHL",i]; [button setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:imageNameSel] forState:UIControlStateSelected]; CGFloat x = i * myView.frame.size.width / 2;
button.frame = CGRectMake(x, 0, myView.frame.size.width / 2, myView.frame.size.height); [myView addSubview:button]; //设置按钮的标记, 方便来索引当前的按钮,并跳转到相应的视图
button.tag = i; [button addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside]; //设置初始显示界面
if (0 == i) {
button.selected = YES;
self.selectedBtn = button; //设置该按钮为选中的按钮
}
}
} //TabBar点击,切换界面
- (void)clickBtn:(UIButton *)button {
//1.先将之前选中的按钮设置为未选中
self.selectedBtn.selected = NO;
//2.再将当前按钮设置为选中
button.selected = YES;
//3.最后把当前按钮赋值为之前选中的按钮
self.selectedBtn = button; //4.跳转到相应的视图控制器. (通过selectIndex参数来设置选中了那个控制器)
self.selectedIndex = button.tag;
} @end

 效果如图所示

 

这种方法是用UIView替代TabBar,自定义性强,可以在view上添加自己想要的各种控件,实现动画效果等。

PSL:本文所牵涉代码,只为提供一个思路,为方便新入门iOS开发者观看,均未抽取,重构,很多东西待优化。大家日常写代码的时候记得养成良好习惯就好。

 

关于iOS自定义UITabBar的几种方法的更多相关文章

  1. iOS拨打电话(三种方法)

    iOS拨打电话(三种方法)  查了很多地方的关于iOS程序拨打电话,大都不全,今天我总结了三种方法,各有不同,拿来给大家分享,希望给大家有所帮助 1,这种方法,拨打完电话回不到原来的应用,会停留在通讯 ...

  2. ipa包如何打包?ios打包ipa的四种方法分享

      今天带来的内容是ios打包ipa的四种方法.总结一下,目前.app包转为.ipa包的方法有以下几种,下面一起来看看吧!    1.Apple推荐的方式,即实用xcode的archive功能 Xco ...

  3. 自定义UITabBar的两种方式

    开发中,经常会遇到各种各样的奇葩设计要求,因为apple提供的UITabBar样式单一,只是简单的"图片+文字"样式,高度49又不可以改变.自定义UITabBar成为了唯一的出路. ...

  4. iOS 自定义layer的两种方式

    在iOS中,你能看得见摸得着的东西基本都是UIView,比如一个按钮,一个标签,一个文本输入框,这些都是UIView: 其实UIView之所以能显示在屏幕上,完全是因为它内部的一个图层 在创建UIVi ...

  5. iOS 批量上传图片的 3 种方法

    AFNetworking 在去年年底升级到了 3.0.这个版本更新想必有很多好处,然而让我吃惊的是,它并没有 batch request 接口.之前的 1.x 版本.2.x 版本都实现了这个很常见的需 ...

  6. Chrome模拟手机浏览器(iOS/Android)的三种方法,亲测无误!

    大网站都有推出自己的手机访问版本页面,不管是新闻类还是视频网站,我们在电脑是无法直接访问到手机网站的,比如我经常访问一个3g.qq.com这个手机站点,如果在电脑上直接打开它,则会跳转到其它页面,一般 ...

  7. 关闭ios虚拟键盘的几种方法

    在iOS应用开发中,有三类视图对象会打开虚拟键盘,进行输入操作,但如何关闭虚拟键盘,却没有提供自动化的方法.这个需要我们自己去实现.这三类视图对象分别是UITextField,UITextView和U ...

  8. 【转】 分析iOS Crash文件:符号化iOS Crash文件的3种方法

    当你的应用提交到AppStore或者各个渠道之后,请问你多久会拿到crash文件?你如何分析crash文件的呢? 上传crash文件 你的应用应当有模块能够在应用程序crash的时候上传crash信息 ...

  9. 用Fiddler可以设置浏览器的UA 和 手动 --Chrome模拟手机浏览器(iOS/Android)的三种方法,亲测无误!

    附加以一种软件的方法是:用Fiddler可以设置浏览器的UA 以下3种方法是手动的 通过伪装User-Agent,将浏览器模拟成Android设备. 第一种方法:新建Chrome快捷方式 右击桌面上的 ...

随机推荐

  1. 如何进行js动态生成option?如何实现二级连动?

    何为二级连动? 首先要明白什么是二级连动!顾名思义,就是一个动,另外一个也跟着一起动 看下面的例子: 这里有一个“市级”的选择列表框,还有一个“县级”的选择列表框,如果“市级”的选择列表框中的值发现变 ...

  2. 腾讯微博java(android)sdk新增微博api详细介绍

    本文主要介绍腾讯微博android sdk中新增微博有关的8个接口,以及使用的示例代码 注意:以下所有的api示例代码都需要先新建QqTSdkService类对象qqTSdkService并初始化,见 ...

  3. 构建移动Web应用程序的技术堆栈

    编写web应用程序时,有很多的技术决策.笔者最近回来编写现代Web应用程序,并希望总结一些曾经在开发周期过程中做了记录零散的想法.这篇文章是关于一套对笔者最近开发的项目有帮助的框架.笔者重温了一些最重 ...

  4. 如何在 iOS 8 中使用 Swift 实现本地通知(下)

    在上集中,我们已经构建了一个简单的待办列表应用(to-do list app),这个应用可以在待办项过期时通过本地通知提醒用户.现在,我们要在之前的基础上添加以下功能:应用图标角标上显示过期待办项的数 ...

  5. mysql 参数read_rnd_buffer_size的真正含义

     http://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html  http://dev.mysql.com/doc/refman/ ...

  6. 何查看Tomcat版本信息

    转自:http://dengjianqiang200.blog.163.com/blog/static/65811920094644354148/ 一般来说,在tomcat启动时就会有版本信息,如: ...

  7. [Android开发]- MVC的架构实现登录模块-1

    本系列博客主要展示一下,在C-S(Client - Server)系统开发当中,如何使用MVC的架构来实现安卓端的一个登录验证的模块.如果你能有基本的数据库开发,WEB开发,和安卓开发的知识,那么理解 ...

  8. Java最重要的21个技术点和知识点之JAVA基础

     (一)Java最重要的21个技术点和知识点之JAVA基础  写这篇文章的目的是想总结一下自己这么多年JAVA培训的一些心得体会,主要是和一些java基础知识点相关的,所以也希望能分享给刚刚入门的Ja ...

  9. js字符串的各种格式的转换 ToString,Format

    1.转换钱的格式,仅限int型,float型,double型 double d = 400; d.ToString("C"); //¥400.00 2.10进制数,仅限int型的数 ...

  10. c#基础--常量(const),只读字段(readonly)

    1.0:常量 常量被关键字const 所修饰 我们来看看常量的demo class Program { static void Main(string[] args) { const string n ...