UITabBarController的使用

  • 前言:

    苹果开发的小伙伴都知道,项目中只要用到了UITabBarController,UITabBarController就是APP的骨架。所以熟练掌握UITabBarController的使用方法才能编写出健壮的APP。

在此介绍UITabBarController在项目中的实现的两种方式,一种使用系统自带的tabbar,一种使用自定义的tabbar。

demo下载地址

使用系统自带的tabbar

UITabBarController由两部分组成,一个是UITabBarController包含的子视图,一个是tabbar。

.h文件
#import <UIKit/UIKit.h>
@interface HSP_tabbar_VC : UITabBarController
@end
.m文件

#import "HSP_tabbar_VC.h"
#import "HHTabBar.h"
#import "AppDelegate.h" #define isIPhoneX ScreenHeight==812 @interface HSP_tabbar_VC () @end #pragma - mark - 使用系统自带tabbar 的方式
@implementation HSP_tabbar_VC - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view. [self loadControllers];
} - (void)loadControllers {
//创建tabBarController
UIViewController *vcA = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"firstVC"];
UIViewController *vcB = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"secondVC"];
UIViewController *vcC = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"thiredVC"];
UIViewController *vcD = [[UIViewController alloc]init];
UIViewController *vcE = [[UIViewController alloc]init];
UIViewController *vcF = [[UIViewController alloc]init];
UIViewController *vcG = [[UIViewController alloc]init]; UINavigationController *nav1 = [[UINavigationController alloc]initWithRootViewController:vcA]; //添加控制器
self.viewControllers = @[nav1,vcB,vcC,vcD,vcE,vcF,vcG]; //设置tabBarButton
nav1.tabBarItem = [[UITabBarItem alloc]initWithTitle:@"首页" image:[UIImage imageNamed:@"home_normal"] selectedImage:[UIImage imageNamed:@"home_highlight"]];
vcB.tabBarItem = [[UITabBarItem alloc]initWithTitle:@"导览" image:[[UIImage imageNamed:@"topics_normal"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] selectedImage:[[UIImage imageNamed:@"topics_highlight"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
vcC.tabBarItem = [[UITabBarItem alloc]initWithTitle:@"资讯" image:[UIImage imageNamed:@"service_normal"] selectedImage:[UIImage imageNamed:@"service_highlight"]];
vcD.tabBarItem = [[UITabBarItem alloc]initWithTitle:@"资讯" image:[UIImage imageNamed:@"service_normal"] selectedImage:[UIImage imageNamed:@"service_highlight"]];
vcE.tabBarItem = [[UITabBarItem alloc]initWithTitle:@"资讯" image:[UIImage imageNamed:@"service_normal"] selectedImage:[UIImage imageNamed:@"service_highlight"]];
vcF.tabBarItem = [[UITabBarItem alloc]initWithTitle:@"资讯" image:[UIImage imageNamed:@"service_normal"] selectedImage:[UIImage imageNamed:@"service_highlight"]];
vcG.tabBarItem = [[UITabBarItem alloc]initWithTitle:@"资讯" image:[UIImage imageNamed:@"service_normal"] selectedImage:[UIImage imageNamed:@"service_highlight"]]; vcB.tabBarItem.imageInsets = UIEdgeInsetsMake(-20, 0, 0, 0); vcC.tabBarItem.badgeValue = @"2";
vcC.tabBarItem.badgeColor = [UIColor redColor]; self.tabBar.tintColor = [UIColor orangeColor]; self.tabBar.backgroundColor = [UIColor redColor];
self.tabBar.backgroundImage = [[UIImage alloc]init];
} @end

以上使用系统自带tabbar应当注意的问题

1. 为标签设置图片时,增加显示原图的方法,否则尺寸不对会出现图片显示不出来的情况。
[[UIImage imageNamed:@"topics_normal"]
imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
2. 标签页是大图片时,设置imageInsets属性避免文字和图片重叠
vcB.tabBarItem.imageInsets = UIEdgeInsetsMake(-20, 0, 0, 0);
3. 通过设置背景图片去除系统自带的模糊效果
 self.tabBar.backgroundImage = [[UIImage alloc]init];

自定义tabbar

自定义tabbar的实现原理:将自定义的View 添加到系统的tabbar上,通过全局的 UITabBarController 类来完成UIViewController之间的切换。

- (void)setSelectedIndex:(NSInteger)index {
for (HHTabBarItem *item in self.tabBarItems) {
if (item.tag == index) {
item.selected = YES;
} else {
item.selected = NO;
}
} AppDelegate *dele = (AppDelegate *)[UIApplication sharedApplication].delegate;
UITabBarController *tabBarController = dele.tabVC;
if (tabBarController) {
tabBarController.selectedIndex = index;
}
}

对tabbar的封装分为两层,HHTabBar 以及 HHTabBarItem

HHTabBar类的主要功能是为每个标签分配frame,然后通过接受HHTabBarItem类的点击事件(HHTabBarItem类继承自UIButton)来切换UIViewController。

.h文件

#import <UIKit/UIKit.h>
#import "HHTabBarItem.h"
#import "UIColor+HexColor.h" #define ScreenWidth [UIScreen mainScreen].bounds.size.width
#define ScreenHeight [UIScreen mainScreen].bounds.size.height
#define NewDefaultColor hexColorAlpha(@"#c77a3a", 1) @protocol LLTabBarDelegate <NSObject> - (void)tabBarDidSelectedRiseButton; @end @interface HHTabBar : UIView @property (nonatomic, copy) NSArray<NSDictionary *> *tabBarItemAttributes;
@property (nonatomic, weak) id <LLTabBarDelegate> delegate; @end .m 文件 #import "HHTabBar.h"
#import "AppDelegate.h" @interface HHTabBar () @property (strong, nonatomic) NSMutableArray *tabBarItems; @end @implementation HHTabBar #pragma mark - Lifecycle - (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame]; if (self) {
[self config];
} return self;
} #pragma mark - Private Method - (void)config {
UIImageView *topLine = [[UIImageView alloc] initWithFrame:CGRectMake(0, -5, ScreenWidth, 5)];
topLine.image = [UIImage imageNamed:@"tapbar_top_line"];
[self addSubview:topLine];
} - (void)setSelectedIndex:(NSInteger)index {
for (HHTabBarItem *item in self.tabBarItems) {
if (item.tag == index) {
item.selected = YES;
} else {
item.selected = NO;
}
} AppDelegate *dele = (AppDelegate *)[UIApplication sharedApplication].delegate;
UITabBarController *tabBarController = dele.tabVC;
if (tabBarController) {
tabBarController.selectedIndex = index;
}
} #pragma mark - Touch Event - (void)itemSelected:(HHTabBarItem *)sender {
[self setSelectedIndex:sender.tag];
} #pragma mark - Setter - (void)setTabBarItemAttributes:(NSArray<NSDictionary *> *)tabBarItemAttributes {
_tabBarItemAttributes = tabBarItemAttributes.copy; CGFloat itemWidth = ScreenWidth / _tabBarItemAttributes.count;
CGFloat tabBarHeight = CGRectGetHeight(self.frame);
NSInteger itemTag = 0;
BOOL passedRiseItem = NO; _tabBarItems = [NSMutableArray arrayWithCapacity:_tabBarItemAttributes.count];
for (id item in _tabBarItemAttributes) {
if ([item isKindOfClass:[NSDictionary class]]) {
NSDictionary *itemDict = (NSDictionary *)item; HHTabBarItemType type = [itemDict[kHHTabBarItemAttributeType] integerValue];
CGRect frame = CGRectMake(itemTag * itemWidth + (passedRiseItem ? itemWidth : 0), 0, itemWidth, tabBarHeight); HHTabBarItem *tabBarItem = [self tabBarItemWithFrame:frame
title:itemDict[kHHTabBarItemAttributeTitle]
normalImageName:itemDict[kHHTabBarItemAttributeNormalImageName]
selectedImageName:itemDict[kHHTabBarItemAttributeSelectedImageName] tabBarItemType:type];
if (itemTag == 0) {
tabBarItem.selected = YES;
[tabBarItem setTitleColor:NewDefaultColor forState:UIControlStateSelected];
} [tabBarItem addTarget:self action:@selector(itemSelected:) forControlEvents:UIControlEventTouchUpInside]; tabBarItem.tag = itemTag;
itemTag++; [_tabBarItems addObject:tabBarItem];
[self addSubview:tabBarItem];
}
}
} - (HHTabBarItem *)tabBarItemWithFrame:(CGRect)frame title:(NSString *)title normalImageName:(NSString *)normalImageName selectedImageName:(NSString *)selectedImageName tabBarItemType:(HHTabBarItemType)tabBarItemType { HHTabBarItem *item = [[HHTabBarItem alloc] initWithFrame:frame];
[item setTitle:title forState:UIControlStateNormal];
[item setTitle:title forState:UIControlStateSelected];
item.titleLabel.font = [UIFont systemFontOfSize:10];
UIImage *normalImage = [UIImage imageNamed:normalImageName];
UIImage *selectedImage = [UIImage imageNamed:selectedImageName];
[item setImage:normalImage forState:UIControlStateNormal];
[item setImage:selectedImage forState:UIControlStateSelected];
[item setTitleColor:[UIColor colorWithWhite:1 alpha:0.6] forState:UIControlStateNormal];
[item setTitleColor:NewDefaultColor forState:UIControlStateSelected];
item.tabBarItemType = tabBarItemType; return item;
} @end

HHTabBarItem类的功能是保持Label的位置不变,宽度随着文本信息的多少变化,同时图片保持与Label的距离恒定,这需要根据图片的大小计算imageView的中心点的位置。

另外传递标签的文字和图片时用到的常量字符串也在HHTabBarItem类中定义。

.h文件

//

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSUInteger, HHTabBarItemType) {
HHTabBarItemNormal = 0,
HHTabBarItemRise,
}; extern NSString *const kHHTabBarItemAttributeTitle ;// NSString
extern NSString *const kHHTabBarItemAttributeNormalImageName;// NSString
extern NSString *const kHHTabBarItemAttributeSelectedImageName;// NSString
extern NSString *const kHHTabBarItemAttributeType;// NSNumber, HHTabBarItemType @interface HHTabBarItem : UIButton @end .m文件 #import "HHTabBarItem.h" static float labelBottom = 3.0;
static float imageLabelDis = 5.0;
static float defaultLabelWidth = 18.0; NSString *const kHHTabBarItemAttributeTitle = @"HHTabBarItemAttributeTitle";
NSString *const kHHTabBarItemAttributeNormalImageName = @"HHTabBarItemAttributeNormalImageName";
NSString *const kHHTabBarItemAttributeSelectedImageName = @"HHTabBarItemAttributeSelectedImageName";
NSString *const kHHTabBarItemAttributeType = @"HHTabBarItemAttributeType"; @implementation HHTabBarItem - (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame]; if (self) {
[self config];
} return self;
} - (instancetype)init {
self = [super init]; if (self) {
[self config];
} return self;
} - (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder]; if (self) {
[self config];
} return self;
} - (void)config {
//self.adjustsImageWhenHighlighted = NO; 网上说有选择后出现灰色背景的情况,目前没有发现。
//self.imageView.contentMode = UIViewContentModeScaleAspectFit;
} - (void)layoutSubviews {
[super layoutSubviews]; [self.titleLabel sizeToFit];
CGSize titleSize = self.titleLabel.frame.size; CGSize imageSize = [self imageForState:UIControlStateNormal].size;
if (imageSize.width != 0 && imageSize.height != 0) {
CGFloat imageViewCenterY = CGRectGetHeight(self.frame) - labelBottom - titleSize.height - imageSize.height / 2 - imageLabelDis;
self.imageView.center = CGPointMake(CGRectGetWidth(self.frame) / 2, imageViewCenterY);
} else {
CGPoint imageViewCenter = self.imageView.center;
imageViewCenter.x = CGRectGetWidth(self.frame) / 2;
imageViewCenter.y = (CGRectGetHeight(self.frame) - titleSize.height) / 2;
self.imageView.center = imageViewCenter;
} CGPoint labelCenter = CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame) - labelBottom - titleSize.height / 2);
self.titleLabel.frame = CGRectMake(0, 0, titleSize.width, defaultLabelWidth);
self.titleLabel.center = labelCenter;
} // 还有一种实现方式是设置 Edge Insets,Xcode 7.0.1 好像有点不开心,在 IB 里面更改一下属性的时候,经常崩溃。。。
/* 位置还有一点不准确,推荐用上面的代码来设置 [self.titleLabel sizeToFit];
CGSize titleSize = self.titleLabel.frame.size;
CGSize imageSize = [self imageForState:UIControlStateNormal].size;
NSInteger titleTopInset = CGRectGetHeight(self.frame) - 3 - titleSize.height;
CGFloat titleRightInset = (CGRectGetWidth(self.frame) - titleSize.width) / 2 + titleSize.width;
[self setTitleEdgeInsets:UIEdgeInsetsMake(titleTopInset, 0, 3, titleRightInset)];
CGFloat imageViewLeftRightInset = (CGRectGetWidth(self.frame) - imageSize.width) / 2;
[self setImageEdgeInsets:UIEdgeInsetsMake(CGRectGetHeight(self.frame) - 3 - 5 - titleSize.height - imageSize.height, imageViewLeftRightInset, 3 + 5 + titleSize.height, imageViewLeftRightInset)]; */ @end

UITabBarController的使用的更多相关文章

  1. UITabBarController 升级定制

    UITabBarController 定制 特点 用法 1.准备工作: 加入你的相关图片,放入了Assets.xcassets; 导入Categroy文件夹(这个里面的文件,在这里不详细说明了,有疑问 ...

  2. UITabBarController 基本定制

    UITabBarController 定制 特点 用法 1.准备好你的tabBar图片及其他图片(哈哈哈!!!!),我的图片都放在了Assets.xcassets中. 2.导入本工程中的Categro ...

  3. 自定义UITabBarController标签视图控制器

    首先创建一个类,继承自UItabBarController 然后在.m文件中: 这里我有两个宏定义: #define WIDTH (myView.frame.size.width / 4) //我在写 ...

  4. 混合使用UITabBarController和UINavigationController

    混合使用这两个控件的好处是我们可以在NavigationBar添加更多的东西,如标题,按钮等.让用户能够获得更多的信息. UITabBarController的属性ViewControllers接受以 ...

  5. 基本组件的使用——UITabBarController

    和UINavigationController的作用差不多,UITabBarController也可以在多个UIViewController中切换 这个控件的使用相对简单,只需要为该控件的viewCo ...

  6. Swift - 重写UIKit框架类的init初始化方法(以UITabBarController为例)

    原来写了篇文章讲UITabBarController的用法,当时是从UIViewController跳转到UITabBarController页面,代码如下: 1 self.presentViewCo ...

  7. iOS 怎么设置 UITabBarController 的第n个item为第一响应者?

    iOS 怎么设置 UITabBarController 的第n个item为第一响应者? UITabBarController 里面有个属性:selectedIndex @property(nonato ...

  8. iOS UITabBarController的使用

    UITabBarController 和 UINavigationController 几乎是iOS APP的标配. UITabBarController分栏(标签栏)控制器, 和UINavigati ...

  9. iOS开发UI篇—UITabBarController简单介绍

    iOS开发UI篇—UITabBarController简单介绍 一.简单介绍 UITabBarController和UINavigationController类似,UITabBarControlle ...

  10. 你真的了解UITabBarController吗?

    一:首先查看一下关于UITabBarController的定义 NS_CLASS_AVAILABLE_IOS(2_0) @interface UITabBarController : UIViewCo ...

随机推荐

  1. 【vue】vue项目引入 Element-UI

    根据vue项目的搭建教程,接下来记录下如何在Vue-cli创建的项目中引入Element-UI. 1.安装直接用命令 (推荐) npm install element-ui 2.直接在根目录下的pac ...

  2. elasticserach 索引删除 源码分析

    索引的构成 在看IndicesService服务中移除索引的前提,先了解一个Index类的构成,也就是索引的一些基本信息,代码贴图如下:   主要的信息就两个:一个是name,表示索引名称,一个是uu ...

  3. PyQt 5 的学习引言

    Python 是我学习的第二门编程语言,第一门编程语言是C. 曾经用C和C++的一个库(easyx库)写过图形界面应用, 感受就是难受又难看, 现在想学一下 PyQt 5 这个python的库, 用博 ...

  4. 【翻译】R 中的设计模式

    目录 R 中的设计模式 不动点算法 包装器模式 接口模式 柯里化(Currying) 闭包(Closures) 缓存模式 计数器模式 R 中的设计模式 本文翻译自 Design Patterns in ...

  5. lua表类型

    Lua的表的定义: typedef struct Table { CommonHeader; lu_byte flags; lu_byte lsizenode; /* log2 of size of ...

  6. 20155338《网络对抗技术》 Exp1 PC平台逆向破解

    20155338<网络对抗技术> Exp1 PC平台逆向破解 实践目标 1.实践的对象是一个名为pwn1的linux可执行文件. 2.该程序正常执行流程是:main调用foo函数,foo函 ...

  7. [arc081F]Flip and Rectangles-[黑白染色]

    Description 传送门 Solution 有一个神秘的结论..我不知道大佬是怎么场上推出来的. 一个黑白染色图,每次可以任意翻转行或列的颜色,如果每个2*2的子矩阵内黑色格子都是偶数个,则可以 ...

  8. tkinter的GUI设计:界面与逻辑分离(一)-- 初次见面

    PyQt实现界面与逻辑分离的设计很是方便,详情可以见我的第一篇博文. 不过本文将使用python的标准库 tkinter,来实现界面与逻辑分离的GUI 设计. 我们来设计一个很简单的程序: 目的:长度 ...

  9. 1-[并发编程]-操作系统OS

    1.为什么要有操作系统 现代的计算机系统主要是由一个或者多个处理器,主存,硬盘,键盘,鼠标,显示器,打印机,网络接口及其他输入输出设备组成. 一般而言,现代计算机系统是一个复杂的系统. 其一:如果每位 ...

  10. P4427 [BJOI2018]求和

    P4427 [BJOI2018]求和 同[TJOI2018]教科书般的扭曲虚空 懒得写了(雾 #include<bits/stdc++.h> #define il inline #defi ...