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. sql server 2000 错误229 拒绝了对象sysobjects 的select 权限

    此问题是权限问题,我的解决办法是因为添加角色的时候勾选太多导致的 !!!!!!千万不要勾选db_denydatareader.

  2. java.lang.NoClassDefFoundError: org/apache/ibatis/mapping/DatabaseIdProvider

    我用的方案是:maven+struts2+spring+mybatis 出现上述错误的原因是: <dependency>            <groupId>org.myb ...

  3. P3133 [USACO16JAN]无线电联系Radio Contact

    题目描述 Farmer John has lost his favorite cow bell, and Bessie the cow has agreed to help him find it! ...

  4. HDU 1074 Doing Homework 状压dp(第一道入门题)

    Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  5. POJ 3356 水LCS

    题目链接: http://poj.org/problem?id=3356 AGTC Time Limit: 1000MS   Memory Limit: 65536K Total Submission ...

  6. OpenGL 混合功能

    一.概念:简言之,即在颜色缓存区和深度缓存区中,新旧颜色的覆盖和替换问题:已经存在于缓存区的为目标颜色,即将进入缓存区的为源颜色: 二.应用场景:在不透明的图形前绘制一个透明的图形: 三.主要代码实现 ...

  7. SQL进阶语法的多表操作

    AS别名 多张表联合操作,如果表多,字段名长,不方便阅读.这里我们可以使用  as  关键字来对字段名设置别名. as也可以省略,看个人喜好,在这里我还是支持把 as 写上,这样我们在面对复杂的SQL ...

  8. 编写Dockerfiles

    指令 docker build通过Dockerfile制作镜像 docker build [PATH] [-f Dockerfile] 其中PATH不写,默认执行指令的当前目录,不要用 /,这样将导致 ...

  9. JSON解析工具——Jackson的简单使用

    什么是Jackson 可以轻松实现Java对象与JSON字符串的转换 准备工作:导包 Jackson的jar all下载地址:http://jackson.codehaus.org/1.7.6/jac ...

  10. OracleLinux安装说明

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL杂记页     回到顶级页面:PostgreSQL索引页 [作者 高健@博客园  luckyjackgao@gmail. ...