内容简介:前段时间,我们产品同学又提了个需求。咳咳,就是想要服务器动态控制tabBar的图片和文字,而且要兼容文字没有的情况下图片撑满,而且图片的显示范围固定。但是系统自带的tabBarItem我试了下是不能固定图片显示范围的,它是根据图片的大小来适应的。所有我就自定义了一套,最终效果如下(最后有demo地址):implementation:implementation:
前段时间,我们产品同学又提了个需求。咳咳,就是想要服务器动态控制tabBar的图片和文字,而且要兼容文字没有的情况下图片撑满,而且图片的显示范围固定。但是系统自带的tabBarItem我试了下是不能固定图片显示范围的,它是根据图片的大小来适应的。所有我就自定义了一套,最终效果如下(最后有demo地址):
1、自定义tabBarItem
@interface CYXTabBarItem : UIView /*未选中的图片*/ @property (nonatomic,strong) UIImage *image; /*选中的图片*/ @property (nonatomic,strong) UIImage *selectedImage; /*标题*/ @property (nonatomic,copy) NSString *title; /*是否是选中*/ @property (nonatomic,assign) BOOL selected; /*最大图片尺寸*/ @property (nonatomic,assign) CGSize maxImageSize; /*最小图片尺寸*/ @property (nonatomic,assign) CGSize minImageSize; /*文字颜色*/ @property (nonatomic,strong) UIColor *titleColor; /*选中的文字颜色*/ @property (nonatomic,strong) UIColor *selectedTitleColor; /*点击*/ @property (nonatomic,strong) void(^selectBlock)(void); /*更新布局方法 设置完之后记得调用*/ -(void)updateImageAndTitle; @end 复制代码
implementation:
@interface CYXTabBarItem()
/*图片*/
@property (nonatomic,strong) UIImageView *imageView;
/*文字*/
@property (nonatomic,strong) UILabel *titleLabel;
@end
@implementation CYXTabBarItem
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self addSubview:self.imageView];
[self addSubview:self.titleLabel];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(11);
make.left.and.right.equalTo(self);
make.top.equalTo(self).offset(35);
}];
__weak __typeof(self) _self = self;
[self setTapActionWithBlock:^{
if (_self.selectBlock) {
_self.selectBlock();
}
}];
}
return self;
}
/*更新布局方法 设置完之后记得调用*/
-(void)updateImageAndTitle{
self.titleLabel.text = self.title;
if (self.selected) {
self.titleLabel.font = [UIFont systemFontOfSize:10.0];
self.titleLabel.textColor = self.selectedTitleColor;
if (self.selectedImage) {
self.imageView.image = self.selectedImage;
}
}else{
self.titleLabel.font = [UIFont boldSystemFontOfSize:10.0];
self.titleLabel.textColor = self.titleColor;
if (self.image) {
self.imageView.image = self.image;
}
}
if ([self.title length]) {
[self.imageView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.height.and.width.mas_equalTo(22);
make.centerX.equalTo(self);
make.top.equalTo(self).offset(5);
}];
}else{
[self.imageView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.height.and.width.mas_equalTo(40);
make.centerX.equalTo(self);
make.top.equalTo(self).offset(5);
}];
}
}
#pragma mark ---G
-(UIImageView*)imageView{
if(!_imageView){
_imageView = [[UIImageView alloc] init];
}
return _imageView;
}
-(UILabel*)titleLabel{
if(!_titleLabel){
_titleLabel = [[UILabel alloc] init];
_titleLabel.font = [UIFont systemFontOfSize:10];
_titleLabel.textColor = [UIColor grayColor];
_titleLabel.textAlignment = NSTextAlignmentCenter;
}
return _titleLabel;
}
复制代码
2、自定义tabBarView
@interface CYXBarView : UIView /*初始化按钮*/ -(void)initButtonWithViewControllers:(NSArray<UIViewController *> * )viewControllers; /*最大图片尺寸*/ @property (nonatomic,assign) CGSize maxImageSize; /*最小图片尺寸*/ @property (nonatomic,assign) CGSize minImageSize; /*文字颜色*/ @property (nonatomic,strong) UIColor *titleColor; /*选中的文字颜色*/ @property (nonatomic,strong) UIColor *selectedTitleColor; /*点击*/ @property (nonatomic,strong) void(^selectBlock)(NSInteger index); @property (nonatomic, assign) NSInteger selectIndex; @end 复制代码
implementation:
@interface CYXBarView()
@property (nonatomic,strong) NSMutableArray<CYXTabBarItem *> *items;
@end
@implementation CYXBarView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.maxImageSize = CGSizeMake(40, 40);
self.minImageSize = CGSizeMake(20, 20);
self.titleColor = [UIColor grayColor];
self.selectedTitleColor = [UIColor redColor];
self.items = [NSMutableArray new];
}
return self;
}
-(void)initButtonWithViewControllers:(NSArray<UIViewController *> * )viewControllers{
[self.items removeAllObjects];
for (UIView * view in self.subviews) {
[view removeFromSuperview];
}
CGFloat itemWidth =screenWidth/viewControllers.count;
for (int i= 0; i<viewControllers.count; i++) {
CYXTabBarItem * item = [[CYXTabBarItem alloc] init];
item.maxImageSize = self.maxImageSize;
item.minImageSize = self.minImageSize;
item.titleColor = self.titleColor;
item.selectedTitleColor = self.selectedTitleColor;
UIViewController * viewController = viewControllers[i];
item.title = [viewController.tabBarItem.title length]?viewController.tabBarItem.title:viewController.title;
item.selectedImage = viewController.tabBarItem.selectedImage;
item.image = viewController.tabBarItem.image;
[self addSubview:item];
[item mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(itemWidth);
make.height.equalTo(self);
make.top.equalTo(self);
make.left.mas_equalTo(i*itemWidth);
}];
[self.items addObject:item];
__weak __typeof(self) _self = self;
item.selectBlock = ^{
_self.selectIndex = i;
if (_self.selectBlock) {
_self.selectBlock(_self.selectIndex);
}
};
[item updateImageAndTitle];
}
self.selectIndex = 0;
}
- (void)setSelectIndex:(NSInteger)selectIndex
{
if (![self.items count]||selectIndex>=[self.items count]) {return;}
// 先把上次选择的item设置为可用
CYXTabBarItem *lastItem = self.items[_selectIndex];
lastItem.selected = NO;
// 再把这次选择的item设置为不可用
CYXTabBarItem *item = self.items[selectIndex];
item.selected = YES;
_selectIndex = selectIndex;
[lastItem updateImageAndTitle];
[item updateImageAndTitle];
}
@end
复制代码
2、自定义tabBar
@class CYXBarView; @interface CYXTabBar : UITabBar @property (nonatomic,strong) CYXBarView *tabBarView; @end 复制代码
implementation:
@interface CYXTabBar ()
@end
@implementation CYXTabBar
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self addSubview:self.tabBarView];
[self.tabBarView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.and.right.and.left.and.bottom.equalTo(self);
}];
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
// 把tabBarView带到最前面,覆盖tabBar的内容
[self bringSubviewToFront:self.tabBarView];
/*隐藏原来的*/
for (UIView *view in self.subviews) {
if ([view isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
view.hidden = YES;
}
}
}
// 重写hitTest方法,让超出tabBar部分也能响应事件
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
if (self.clipsToBounds || self.hidden || (self.alpha == 0.f)) {
return nil;
}
UIView *result = [super hitTest:point withEvent:event];
// 如果事件发生在tabbar里面直接返回
if (result) {
return result;
}
// 这里遍历那些超出的部分就可以了,不过这么写比较通用。
for (UIView *subview in self.tabBarView.subviews) {
// 把这个坐标从tabbar的坐标系转为subview的坐标系
CGPoint subPoint = [subview convertPoint:point fromView:self];
result = [subview hitTest:subPoint withEvent:event];
// 如果事件发生在subView里就返回
if (result) {
return result;
}
}
return nil;
}
#pragma mark ---G
-(CYXBarView*)tabBarView{
if(!_tabBarView){
_tabBarView = [[CYXBarView alloc] init];
}
return _tabBarView;
}
复制代码
2、自定义UITabBarController
@interface CYXTabBarViewController : UITabBarController @end 复制代码
implementation:
@interface CYXTabBarViewController ()
@property (nonatomic,strong) CYXTabBar *customTabBar;
@end
@implementation CYXTabBarViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self setValue:self.customTabBar forKey:@"tabBar"];
[self initViewControllers];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.selectedIndex = 3;
});
}
-(void)initViewControllers{
NSMutableArray * viewControllers = [NSMutableArray new];
UIViewController *homeVC = [[UIViewController alloc] init];
homeVC.view.backgroundColor = [UIColor redColor];
[viewControllers addObject:[self addChildViewController:homeVC title:@"首页" imageNamed:@"tabBar_home"]];
UIViewController *expoVC = [[UIViewController alloc] init];
expoVC.view.backgroundColor = [UIColor yellowColor];
[viewControllers addObject:[self addChildViewController:expoVC title:@"家博会" imageNamed:@"tabBar_activity"]];
UIViewController *activityVC = [[UIViewController alloc] init];
activityVC.view.backgroundColor = [UIColor yellowColor];
[viewControllers addObject:[self addChildViewController:activityVC title:@"" imageNamed:@"tabBar_activity"]];
UIViewController *findVC = [[UIViewController alloc] init];
findVC.view.backgroundColor = [UIColor blueColor];
[viewControllers addObject:[self addChildViewController:findVC title:@"发现" imageNamed:@"tabBar_find"]];
UIViewController *mineVC = [[UIViewController alloc] init];
mineVC.view.backgroundColor = [UIColor greenColor];
[viewControllers addObject:[self addChildViewController:mineVC title:@"我的" imageNamed:@"tabBar_mine"]];
self.viewControllers = viewControllers;
}
// 添加某个 childViewController
- (UINavigationController *)addChildViewController:(UIViewController *)vc title:(NSString *)title imageNamed:(NSString *)imageNamed
{
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
// 如果同时有navigationbar 和 tabbar的时候最好分别设置它们的title
vc.navigationItem.title = title;
nav.tabBarItem.title = title;
nav.tabBarItem.image = [UIImage imageNamed:imageNamed];
nav.tabBarItem.selectedImage = [UIImage imageNamed:@"jmtIconBg"];
return nav;
}
-(void)setViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers{
[super setViewControllers:viewControllers];
[self.customTabBar.tabBarView initButtonWithViewControllers:viewControllers];
}
-(void)setSelectedIndex:(NSUInteger)selectedIndex{
[super setSelectedIndex:selectedIndex];
self.customTabBar.tabBarView.selectIndex = selectedIndex;
}
#pragma mark ---G
-(CYXTabBar*)customTabBar{
if(!_customTabBar){
_customTabBar = [[CYXTabBar alloc] init];
__weak __typeof(self) _self = self;
_customTabBar.tabBarView.selectBlock = ^(NSInteger index) {
_self.selectedIndex = index;
};
}
return _customTabBar;
}
复制代码
Appdelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor whiteColor];
self.window.rootViewController = [[CYXTabBarViewController alloc] init];
// 设置这个窗口有主窗口并显示
[self.window makeKeyAndVisible];
return YES;
}
复制代码
这样就实现上图所示效果图了,高度自定义化,可随意修改。欢迎讨论指教 demo: github.com/SionChen/CY…
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Android 自定义 View (04自定义属性)
- Vue自定义组件(简单实现一个自定义组件)
- Android 自定义View:深入理解自定义属性(七)
- Qt编写自定义控件20-自定义饼图 原 荐
- SpringBoot2 | SpringBoot自定义AutoConfiguration | SpringBoot自定义starter(五)
- 『互联网架构』软件架构-springboot自定义视图和自定义Starter(90)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
计算机科学概论(第11版)
J. Glenn Brookshear / 刘艺、肖成海、马小会、毛倩倩 / 人民邮电出版社 / 2011-10-1 / 69.00元
本书多年来一直深受世界各国高校师生的欢迎,是美国哈佛大学、麻省理工学院、普林斯顿大学、加州大学伯克利分校等许多著名大学的首选教材,对我国的高校教学也产生了广泛影响。 本 书以历史眼光,从发展的角度、当前的水平以及现阶段的研究方向等几个方面,全景式描绘了计算机科学各个子学科的主要领域。在内容编排上,本书很好地兼顾了 学科广度和主题深度,把握了最新的技术趋势。本书用算法、数据抽象等核心思想贯穿各......一起来看看 《计算机科学概论(第11版)》 这本书的介绍吧!