iOS开发笔记2 - 自定义tabbar
来源:互联网 发布:战舰少女r重炮改数据 编辑:程序博客网 时间:2024/04/26 03:12
在开发过程中,TabBarController是几乎每个APP都需要用到的,其内部默认包含一个UITabBar,但这个TabBar并不是很好用,所以我们需要自定义TabBar及上面的Button,以实现我们自己想要的效果。
接下来我们开始自定义。
首先是TabBar的.h文件:
#import <UIKit/UIKit.h>@class DYHTabbar;@protocol DYHTabbarDelegate<NSObject>@optional-(void)tabBar:(DYHTabbar *)tabBar didSelectButtonFrom:(int)from To:(int)to;@end@interface DYHTabbar : UIView@property (nonatomic,weak) id<DYHTabbarDelegate> delegate;-(void)addButtonWithATabbarItem:(UITabBarItem* )item;@end
分析:
1.自定义的TabBar只需要能够在上面放置按钮即可,故我们继承自UIView即可。
2.自定义的TabBar上面的按钮有几个,内容如何,应该由控制器决定,故我们只需要提供API: addButtonWithATabbarItem
让控制器传递一个系统自带的TabBarItem模型给Tabbar来添加按钮
3.很明显控制器需要监听TabBar上按钮的点击,来切换子控制器,故我们定义一个代理协议,由控制器实现
接下来是TabBar的.m文件
#import "DYHTabbar.h"#import "DYHTabbarButton.h"@interface DYHTabbar()@property (nonatomic,strong) NSMutableArray* buttons;@property (nonatomic,weak) DYHTabbarButton* selectedButton;@end@implementation DYHTabbar-(NSMutableArray *)buttons{ if (_buttons == nil) { _buttons = [NSMutableArray array]; } return _buttons;}-(void)addButtonWithATabbarItem:(UITabBarItem *)item{ DYHTabbarButton* button = [[DYHTabbarButton alloc]init]; [self addSubview:button]; button.item = item; [button addTarget:self action:@selector(buttonClick:)forControlEvents:UIControlEventTouchDown]; [self.buttons addObject:button]; if (self.buttons.count == 1) { [self buttonClick:button]; }}-(void)buttonClick:(DYHTabbarButton *)button{ NSLog(@"buttonClick:"); if ([self.delegaterespondsToSelector:@selector(tabBar:didSelectButtonFrom:To:)]) { [self.delegate tabBar:selfdidSelectButtonFrom:self.selectedButton.tag To:button.tag]; } self.selectedButton.selected = NO; button.selected = YES; self.selectedButton = button;}-(void)layoutSubviews{ [super layoutSubviews]; CGFloat tabBarH = self.frame.size.height; CGFloat tabBarW = self.frame.size.width; CGFloat buttonW = tabBarW / self.buttons.count; CGFloat buttonH = tabBarH; CGFloat buttonY = 0; for (int i = 0; i<self.buttons.count ; i++) { //取出按钮 DYHTabbarButton* button = self.buttons[i]; //设置按钮的frame CGFloat buttonX = i*buttonW; button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH); //绑定TAG button.tag = i; }}@end
分析:
1.tabbar需要访问内部的按钮,故有数组buttons
2.tabbar需要知道当前被选中的按钮,故有属性selectedButton
3.buttons是mutableArray,故进行懒加载
4.addbutton,添加按钮,接收UITabBarItem模型以设置按钮属性,默认点击第一个按钮,并且每个按钮被点击通知Tabbar
5.buttonClick:按钮被点击的回调方法,由于Tabbar本身没有改变控制器的能力,故必须通知其控制器,执行代理方法,整个消息路径是 button被点击--(通知)-->Tabbar--(通知)-->控制器->执行切换控制器操作。另外,在这个方法中需要设置按钮的点击状态(样式变化)以及Tabbar的selectedButton
6.layoutSubviews,在TabBar加载时自动调用,算出按钮的frame,很简单的算法,要注意的是这里需要set一下按钮的tag值,用来标记这是第几个按钮。
接下来我们来看看自定义的button,由于我们自定义的整个Tabbar本身是透明的,故实际显示的效果全看我们自定义的Button。
.h文件
#import <UIKit/UIKit.h>@interface DYHTabbarButton : UIButton@property (nonatomic,strong) UITabBarItem* item;@end
分析:
1.没什么好说的,一个模型属性来接收模型
.m文件
#import "DYHTabbarButton.h"//图标比例#define DYHTabBarButtonImageRatio 0.7//按钮默认文字颜色#define DYHTabBarButtonTitleColor (iOS7 ? [UIColor blackColor] : [UIColor whiteColor])//选中文字颜色#define DYHTabBarButtonTitleSlectedColor (iOS7 ? DYHColor(234,103,0) : DYHColor(248,139,0))@implementation DYHTabbarButton- (id)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { self.imageView.contentMode =UIViewContentModeCenter; self.titleLabel.textAlignment = NSTextAlignmentCenter; self.titleLabel.font = [UIFont systemFontOfSize:10]; [self setTitleColor:DYHTabBarButtonTitleColorforState:UIControlStateNormal]; [self setTitleColor:DYHTabBarButtonTitleSlectedColorforState:UIControlStateSelected]; } return self;}-(void)setItem:(UITabBarItem *)item{ _item = item; //KVO 监听属性 [item addObserver:self forKeyPath:@"badgeValue"options:0 context:nil]; [item addObserver:self forKeyPath:@"title" options:0context:nil]; [item addObserver:self forKeyPath:@"image" options:0context:nil]; [item addObserver:self forKeyPath:@"selectedImage"options:0 context:nil]; [self observeValueForKeyPath:nil ofObject:nil change:nilcontext:nil];}//监听到某个对象的属性改变了就会调用-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ //设置文字和图片 [self setTitle:self.item.title forState:UIControlStateNormal]; [self setImage:self.item.imageforState:UIControlStateNormal]; [self setImage:self.item.selectedImageforState:UIControlStateSelected]; }-(void)dealloc{ [self removeObserver:self forKeyPath:@"badgeValue"]; [self removeObserver:self forKeyPath:@"title"]; [self removeObserver:self forKeyPath:@"image"]; [self removeObserver:self forKeyPath:@"selectedImage"];}-(CGRect)titleRectForContentRect:(CGRect)contentRect{ CGFloat titleY =contentRect.size.height*DYHTabBarButtonImageRatio; CGFloat titleW =contentRect.size.width; return CGRectMake(0, titleY, titleW , contentRect.size.height - titleY); }-(CGRect)imageRectForContentRect:(CGRect)contentRect{ CGFloat imageW = contentRect.size.width; CGFloat imageH = contentRect.size.height*DYHTabBarButtonImageRatio; return CGRectMake(0, 0, imageW, imageH);}@end
分析: 1.init没什么好说的,设置一些颜色字体,根据需求来
2.setItem,读取模型数据的方法,需要注意的是这里我们使Item监听自己的值改变,为的是完善逻辑,使用button.item.属性同样也能更改button的样式;另外我们默认调用一次值改变回调方法,初始化。
3.值改变回调方法,没什么好说的,根据值改变设置按钮属性
4.dealloc方法,在这个对象被销毁时停止监听
5,6用来设置按钮上的文字和图片的显示样式
至此我们的自定义Tabbar完成了,不过controller在使用的时候还有一些要注意的(我们默认使用UITabBarController及其子类):
1.需要写如下代码
-(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; for (UIView *child in self.tabBar.subviews) { if ([child isKindOfClass:[UIControl class]]) { [child removeFro}mSuperview]; } }
因为tabBarController内部本身有一个TabBar,执行addChildController操作后默认tabbar也会加上按钮,需要移除这些按钮,否则会造成显示错误。
2.实现代理方法:
-(void)tabBar:(DYHTabbar *)tabBar didSelectButtonFrom:(int)from To:(int)to{ self.selectedIndex = to;}
由于tabBarController本身重写了selectedIndex的set方法,并且我们传的值恰好与子控制器顺序相对应,故只需要这一句代码即可完成切换
0 0
- iOS开发笔记2 - 自定义tabbar
- iOS 开发 自定义Tabbar
- iOS开发: 自定义tabBar
- iOS开发中 自定义TabBar
- IOS开发UI:自定义TabBar
- iOS开发, tabbar自定义图片
- ios开发-UI-自定义Tabbar 图书布局
- IOS之自定义tabbar
- ios 自定义TabBar
- iOS 自定义tabbar
- iOS Swift 自定义tabbar
- IOS 自定义tabbar
- iOS自定义tabbar
- iOS 自定义tabBar
- iOS -- 自定义TabBar
- iOS自定义TabBar
- ios中自定义tabBar
- ios中自定义tabBar
- MySQL安装视频教程
- 免费开源的嵌入式 OS、GUI、fs、数据库等
- 通州新城玉带河大街雨水方沟工程完成并交付使用
- 堆栈经典应用-表达式求值
- iOS升到8.2收不到推送问题的解决(You've implemented -[ application:didReceiveRemoteNotification:fetchCompletionH )
- iOS开发笔记2 - 自定义tabbar
- linux下iconv()函数的用法
- A Note on Distributed Computing
- 手机端链接点击是会出现边框
- 在拼接的字符串中根据代码显示名称
- Maven简介(三)——profile介绍
- LUA中的正则表达式
- Java之List
- 使用Android MediaStore裁剪大图片初次探究