tabbarItem
.h文件
//
// JHKTabBarItem.h
// TestBaseView
//
// Created by 金英杰 on 2020/11/14.
//
@protocol JHKTabBarItemDelegate;
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface JHKTabBarItem : UIView
@property (nonatomic, copy) NSString *icon;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, strong) UIColor *titleColor;
@property (nonatomic, assign) id <JHKTabBarItemDelegate> delegate;
@end
@protocol JHKTabBarItemDelegate <NSObject>
- (void)tabBarItem:(JHKTabBarItem *)item didSelectIndex:(NSInteger)index;
@end
NS_ASSUME_NONNULL_END
.m文件
//
// JHKTabBarItem.m
// TestBaseView
//
// Created by 金英杰 on 2020/11/14.
//
#import "JHKTabBarItem.h"
#import "JHKTabBarItem.h"
static NSInteger defaultTag = 100000;
@interface JHKTabBarItem ()
@property (nonatomic, strong)UIImageView *iconImageView;
@property (nonatomic, strong)UILabel *titleLabel;
@end
@implementation JHKTabBarItem
- (instancetype)init {
self = [super init];
if (self) {
self.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(itemClicked:)];
[self addGestureRecognizer:tap];
}
return self;
}
// 重写setTag方法
- (void)setTag:(NSInteger)tag {
[super setTag:tag + defaultTag];
}
- (UIImageView *)iconImageView {
if (_iconImageView == nil) {
_iconImageView = [[UIImageView alloc]init];
_iconImageView.contentMode = UIViewContentModeScaleAspectFit;
[self addSubview:_iconImageView];
}
return _iconImageView;
}
- (UILabel *)titleLabel {
if (_titleLabel == nil) {
_titleLabel = [[UILabel alloc]init];
_titleLabel.textAlignment = NSTextAlignmentCenter;
_titleLabel.font = [UIFont systemFontOfSize:10];
_titleLabel.numberOfLines = 0;
_titleLabel.textColor = [UIColor grayColor];
[self addSubview:_titleLabel];
}
return _titleLabel;
}
- (void)setIcon:(NSString *)icon {
_icon = icon;
self.iconImageView.image = [UIImage imageNamed:icon];
}
- (void)setTitle:(NSString *)title {
_title = title;
self.titleLabel.text = title;
}
- (void)setTitleColor:(UIColor *)titleColor {
_titleColor = titleColor;
self.titleLabel.textColor = titleColor;
}
- (void)layoutSubviews {
[super layoutSubviews];
CGFloat space = 6.0;
if (self.icon.length > 0 && self.title.length > 0) {
CGFloat iconHeight = (CGRectGetHeight(self.frame)- jTabBarBottomHeight - space * 3)*2/3.0 ;
self.iconImageView.frame = CGRectMake(space, space, CGRectGetWidth(self.frame) - 2 * space, iconHeight);
self.titleLabel.frame = CGRectMake(space, CGRectGetMaxY(self.iconImageView.frame) + space, CGRectGetWidth(self.frame) - 2*space,iconHeight/2.0);
} else if (self.icon.length > 0) {
self.iconImageView.frame = CGRectMake(2, 2, CGRectGetWidth(self.frame) - 4, CGRectGetHeight(self.frame) - 4);
} else if (self.title.length > 0) {
self.titleLabel.frame = CGRectMake(2, CGRectGetHeight(self.frame) - 22, CGRectGetWidth(self.frame) - 4, 20);
}
}
- (void)itemClicked:(UITapGestureRecognizer *)tap {
if (self.delegate && [self.delegate respondsToSelector:@selector(tabBarItem:didSelectIndex:)]) {
[self.delegate tabBarItem:self didSelectIndex:self.tag - defaultTag];
}
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
@end
tabbar
.h文件
//
// JHKTabBar.h
// TestBaseView
//
// Created by 金英杰 on 2020/11/14.
//
#import <UIKit/UIKit.h>
@class JHKTabBarItem;
@protocol JHKTabBarDelegate;
NS_ASSUME_NONNULL_BEGIN
@interface JHKTabBar : UIView
@property (nonatomic, strong)NSArray<JHKTabBarItem *> *items;
@property (nonatomic, assign)id <JHKTabBarDelegate> delegate;
@end
@protocol JHKTabBarDelegate <NSObject>
- (void)tabBar:(JHKTabBar *)tab didSelectItem:(JHKTabBarItem *)item atIndex:(NSInteger)index ;
@end
NS_ASSUME_NONNULL_END
.m文件
//
// JHKTabBar.m
// TestBaseView
//
// Created by 金英杰 on 2020/11/14.
//
#import "JHKTabBar.h"
#import "JHKTabBarItem.h"
@interface JHKTabBar ()<JHKTabBarItemDelegate>
@property (nonatomic, strong) UIVisualEffectView *effectView;
@property (nonatomic, strong) UIView *topLine;
@end
@implementation JHKTabBar
- (instancetype)init {
self = [super init];
if (self) {
self.backgroundColor = [UIColor whiteColor];
}
return self;
}
- (UIView *)topLine {
if (_topLine == nil) {
_topLine = [[UIView alloc]init];
_topLine.backgroundColor = jColorWithHex(0xC2C2C2);
[self addSubview:_topLine];
}
return _topLine;
}
- (UIVisualEffectView *)effectView {
if (_effectView == nil) {
UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
_effectView = [[UIVisualEffectView alloc] initWithEffect:effect];
_effectView.alpha = 1.0;
[self addSubview:_effectView];
}
return _effectView;
}
- (void)layoutSubviews {
[super layoutSubviews];
self.effectView.frame = self.bounds;
[self setupItems];
self.topLine.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), 0.3);
}
- (void)setupItems {
CGFloat width = CGRectGetWidth(self.frame)/self.items.count;
CGFloat height = CGRectGetHeight(self.frame);
for (int i = 0; i < self.items.count; i++) {
JHKTabBarItem *item = [self.items objectAtIndex:i];
item.frame = CGRectMake(i*width, 0, width, height);
[self addSubview:item];
item.delegate = self;
}
}
- (void)tabBarItem:(JHKTabBarItem *)item didSelectIndex:(NSInteger)index {
if (self.delegate && [self.delegate respondsToSelector:@selector(tabBar:didSelectItem:atIndex:)]) {
[self.delegate tabBar:self didSelectItem:item atIndex:index];
}
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
@end
config文件
.h
//
// JHKTabBarConfig.h
// TestBaseView
//
// Created by 金英杰 on 2020/11/14.
// 这个类的主要作用是: 提供数据源, 绘制底部tabBar, 及关联viewController;
#pragma mark - JHKTabBarConfig
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface JHKTabBarConfig : NSObject
/**
控制器数组, 必须设置
*/
@property (nonatomic, strong) NSArray *viewControllers;
/**
item标题数组, 选择设置
*/
@property (nonatomic, strong) NSArray *titles;
/**
是否是导航, 默认 YES
*/
@property (nonatomic, assign) BOOL isNavigation;
/**
选中状态下的图片数组
*/
@property (nonatomic, strong) NSArray *selectedImages;
/**
正常状态下的图片数组
*/
@property (nonatomic, strong) NSArray *normalImages;
/**
选中状态下的标题颜色 默认: red
*/
@property (nonatomic,strong) UIColor *selectedColor;
/**
正常状态下的标题颜色 默认: gray
*/
@property (nonatomic, strong) UIColor *normalColor;
@end
NS_ASSUME_NONNULL_END
.m
//
// JHKTabBarConfig.m
// TestBaseView
//
// Created by 金英杰 on 2020/11/14.
//
#import "JHKTabBarConfig.h"
@implementation JHKTabBarConfig
- (instancetype)init {
self = [super init];
if (self) {
_isNavigation = YES;
_normalColor = [UIColor grayColor];
_selectedColor = jColorWithHex(0xF85959);
}
return self;
}
@end
controller
.h
//
// JHKTabBarController.h
// TestBaseView
//
// Created by 金英杰 on 2020/11/14.
//
#import <UIKit/UIKit.h>
@class JHKTabBarConfig;
typedef JHKTabBarConfig*_Nonnull(^tabBarBlock)(JHKTabBarConfig * _Nullable config);
NS_ASSUME_NONNULL_BEGIN
@interface JHKTabBarController : UITabBarController
/**
是否可用自动旋转屏幕
*/
@property (nonatomic, assign) BOOL isAutoRotation;
/**
创建tabBarController
@param block 配置创建tabBarController所需的参数
@return 返回tabBarController实例对象
*/
+ (instancetype)createTabBarController:(tabBarBlock)block;
/**
获取当前的tabBarController实例, 实例创建后可通过此方法获取当前实例
@return 返回tabBarController实例对象
*/
+ (instancetype)defaultTabBarController;
/**
隐藏底部tabBar的方法
@param isAnimation 是否需要动画
*/
- (void)hiddenTabBarWithAnimation:(BOOL)isAnimation;
/**
显示底部tabBar的方法
@param isAnimation 是否需要动画
*/
- (void)showTabBarWithAnimation:(BOOL)isAnimation;
@end
NS_ASSUME_NONNULL_END
.m
//
// JHKTabBarController.m
// TestBaseView
//
// Created by 金英杰 on 2020/11/14.
//
#import "JHKTabBarController.h"
#import "JHKTabBar.h"
#import "JHKTabBarConfig.h"
#import "JHKTabBarItem.h"
@interface JHKTabBarController ()<JHKTabBarDelegate>
@property (nonatomic, strong) JHKTabBar *customTabBar;
@property (nonatomic, strong) JHKTabBarConfig *config;
@end
@implementation JHKTabBarController
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.navigationBar.hidden = YES;
self.view.backgroundColor = [UIColor whiteColor];
self.selectedIndex = 0;
// Do any additional setup after loading the view.
}
- (JHKTabBar *)customTabBar {
if (_customTabBar == nil) {
_customTabBar = [[JHKTabBar alloc]init];
_customTabBar.delegate = self;
}
return _customTabBar;
}
+ (instancetype)createTabBarController:(tabBarBlock)block {
static dispatch_once_t onceToken;
static JHKTabBarController *tabBar;
dispatch_once(&onceToken, ^{
tabBar = [[JHKTabBarController alloc]initWithBlock:block];
});
return tabBar;
}
+ (instancetype)defaultTabBarController {
return [JHKTabBarController createTabBarController:nil];
}
- (void)hiddenTabBarWithAnimation:(BOOL)isAnimation {
if (isAnimation) {
[UIView animateWithDuration:0.2 animations:^{
self.customTabBar.alpha = 0;
}];
} else {
self.customTabBar.alpha = 0;
}
}
- (void)showTabBarWithAnimation:(BOOL)isAnimation {
if (isAnimation) {
[UIView animateWithDuration:0.2 animations:^{
self.customTabBar.alpha = 1.0;
}];
} else {
self.customTabBar.alpha = 1.0;
}
}
- (instancetype)initWithBlock:(tabBarBlock)block {
self = [super init];
if (self) {
JHKTabBarConfig *config = [[JHKTabBarConfig alloc]init];
NSAssert(block, @"Param in zhe function, can not be nil");
if (block) {
_config = block(config);
}
NSAssert(_config.viewControllers, @"Param 'viewControllers' in the 'config', can not be nil");
[self setupViewControllers];
[self setupTabBar];
_isAutoRotation = YES;
}
return self;
}
- (void)setupViewControllers {
if (_config.isNavigation) {
NSMutableArray *vcs = [NSMutableArray arrayWithCapacity:_config.viewControllers.count];
for (UIViewController *vc in _config.viewControllers) {
if (![vc isKindOfClass:[UINavigationController class]]) {
// UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:vc];
[vcs addObject:vc];
} else {
[vcs addObject:vc];
}
}
self.viewControllers = [vcs copy];
} else {
self.viewControllers = [_config.viewControllers copy];
}
}
- (void)setupTabBar {
NSMutableArray *items = [NSMutableArray array];
for (int i = 0; i < _config.viewControllers.count; i++) {
JHKTabBarItem *item = [[JHKTabBarItem alloc]init];
if (i == 0) {
item.icon = _config.selectedImages[i];
if (_config.titles.count > 0) {
item.titleColor = _config.selectedColor;
}
} else {
item.icon = _config.normalImages[i];
if (_config.titles.count > 0) {
item.titleColor = _config.normalColor;
}
}
if (i < _config.titles.count) {
item.title = _config.titles[i];
}
[items addObject:item];
item.tag = i;
}
// 隐藏掉系统的tabBar
self.tabBar.hidden = YES;
self.customTabBar.items = [items copy];
self.customTabBar.frame = CGRectMake(0, CGRectGetHeight(self.view.frame) - jTabbarHeight, CGRectGetWidth(self.view.frame), jTabbarHeight);
[self.view addSubview:self.customTabBar];
}
#pragma mark - JHKTabBarDelegate
- (void)tabBar:(JHKTabBar *)tab didSelectItem:(JHKTabBarItem *)item atIndex:(NSInteger)index {
NSMutableArray *items = [NSMutableArray arrayWithCapacity:0];
for (UIView *view in tab.subviews) {
if ([view isKindOfClass:[JHKTabBarItem class]]) {
[items addObject:view];
}
}
for (int i = 0; i < items.count; i++) {
UIView *view = items[i];
if ([view isKindOfClass:[JHKTabBarItem class]]) {
JHKTabBarItem *item = (JHKTabBarItem *)view;
item.icon = self.config.normalImages[i];
if (self.config.titles.count > 0) {
item.titleColor = _config.normalColor;
}
}
}
item.icon = self.config.selectedImages[index];
if (self.config.titles.count > 0) {
item.titleColor = self.config.selectedColor;
}
self.selectedIndex = index;
}
// 屏幕旋转时调整tabbar
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
self.customTabBar.frame = CGRectMake(0, size.height - jTabbarHeight, size.width, jTabbarHeight);
}
- (BOOL)shouldAutorotate {
return self.isAutoRotation;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
if (self.isAutoRotation) {
return UIInterfaceOrientationMaskAllButUpsideDown;
} else {
return UIInterfaceOrientationMaskPortrait;
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
appdelegate中使用
JHKTabBarConfig *tabBarConfig = [[JHKTabBarConfig alloc]init];
tabBarConfig.viewControllers = @[vc,vc1,vc2,vc3];
tabBarConfig.selectedImages = @[@"Image0",@"Image2",@"Image4",@"Image6"];
tabBarConfig.normalImages = @[@"Image1",@"Image3",@"Image5",@"Image7"];
tabBarConfig.titles = @[@"头条",@"西瓜视频",@"消息",@"放映厅"];
JHKTabBarController *tabBarController = [JHKTabBarController createTabBarController:^JHKTabBarConfig *(JHKTabBarConfig *config) {
return tabBarConfig;
}];
UINavigationController *controller = [[UINavigationController alloc]initWithRootViewController:tabBarController];
tabBarController.navigationController.navigationBar.hidden = YES;
self.window.rootViewController = controller;
[self.window makeKeyAndVisible];
这里window的rootcontroller 要设置成nav下的tabbar。是因为 这个是自定义的tab 在push的时候没法使用 hidenavwhenpush 那个方法来隐藏tabbar