自定义UITabBarController子类

UITabBarController的tabBar往往不能满足我们的需求

通过自定义UITabBarController子类自定义标签栏是经常采用的方式。

基本步骤:

1)定义UIButton子类作为标签按钮

2)定义模型类,管理每个页面的控制器以及对应标签栏上的数据

3)自定义标签栏

4)定义UITabBarController子类



定义标签按钮

添加两种创建方法:只显示图片和文字图片都显示的

+(AMTabBarButton*)tabBarButtonWithTitle:(NSString*)titlenormalImage:(UIImage*)normalImageselectedImage:(UIImage*)selectedImage{AMTabBarButton*btn=[AMTabBarButtonbuttonWithType:UIButtonTypeCustom];[btnsetImage:normalImageforState:UIControlStateNormal];[btnsetImage:selectedImageforState:UIControlStateSelected];[btnsetTitle:titleforState:UIControlStateNormal];[btnsetTitleColor:[UIColorgrayColor]forState:UIControlStateNormal];[btnsetTitleColor:[UIColororangeColor]forState:UIControlStateSelected];btn.titleLabel.font=[UIFontsystemFontOfSize:10];btn.titleLabel.textAlignment=NSTextAlignmentCenter;returnbtn;}+(AMTabBarButton*)tabBarButtonWithNormalImage:(UIImage*)normalImageselectedImage:(UIImage*)selectedImage{AMTabBarButton*btn=[AMTabBarButtonbuttonWithType:UIButtonTypeCustom];[btnsetImage:normalImageforState:UIControlStateNormal];[btnsetImage:selectedImageforState:UIControlStateSelected];[btnsetTitle:nilforState:UIControlStateNormal];returnbtn;}

修改按钮内部label和p_w_picpathView的位置,重写以下方法即可

-(CGRect)titleRectForContentRect:(CGRect)contentRect-(CGRect)p_w_picpathRectForContentRect:(CGRect)contentRect

如:

-(CGRect)p_w_picpathRectForContentRect:(CGRect)contentRect{CGFloatx,y,w,h;if([selftitleForState:UIControlStateNormal]==nil){w=h=contentRect.size.height*0.8;}else{w=h=contentRect.size.height*0.45;}x=contentRect.size.width/2-w/2;y=contentRect.size.height*0.1;returnCGRectMake(x,y,w,h);}-(CGRect)titleRectForContentRect:(CGRect)contentRect{CGFloatx,y,w,h;if([selftitleForState:UIControlStateNormal]==nil){returnCGRectZero;}h=contentRect.size.height*0.25;w=contentRect.size.width*0.6;x=contentRect.size.width*0.2;y=contentRect.size.height*0.65;returnCGRectMake(x,y,w,h);}

取消按钮点击时的高亮效果:重写highlighted属性的setter方法

-(void)setHighlighted:(BOOL)highlighted{}


定义模型类

管理每个子控制器及标签栏上按钮的数据

@interfaceAMTabBarItemModel:NSObject@property(nonatomic,copy)UIImage*normalImage;@property(nonatomic,copy)UIImage*selectedImage;@property(nonatomic,copy)NSString*title;@property(nonatomic,strong)UIViewController*viewController;+(instancetype)tabBarItemModelWithNormalImage:(UIImage*)normalImageselectedImage:(UIImage*)selectedImagetitle:(NSString*)titleviewController:(UIViewController*)viewController;@end

定义标签栏

定义一个UIView的子类作为自定义的标签类

设置样式属性,两种样式:只有图片和文字图片都有的

typedefenum{AMTabBarStyleTitleAndImage,AMTabBarStyleImageOnly}AMTabBarStyle;

创建方法:

+(instancetype)tabBarViewWithItemModels:(NSArray*)modelstabBarStyle:(AMTabBarStyle)tabBarStyle{return[[selfalloc]initWithItemModels:modelstabBarStyle:tabBarStyle];}-(instancetype)initWithItemModels:(NSArray*)modelstabBarStyle:(AMTabBarStyle)tabBarStyle{if(self=[superinit]){self.tabBarStyle=tabBarStyle;inti=1;for(AMTabBarItemModel*modelinmodels){AMTabBarButton*btn;if(tabBarStyle==AMTabBarStyleTitleAndImage){btn=[AMTabBarButtontabBarButtonWithTitle:model.titlenormalImage:model.normalImageselectedImage:model.selectedImage];}else{btn=[AMTabBarButtontabBarButtonWithNormalImage:model.normalImageselectedImage:model.selectedImage];}[selfaddSubview:btn];[btnaddTarget:selfaction:@selector(itemBtnClicked:)forControlEvents:UIControlEventTouchDown];btn.tag=i;i++;}self.selectedBtn=self.subviews[0];}returnself;}-(void)layoutSubviews{[superlayoutSubviews];CGFloatx,y,w,h;h=self.frame.size.height;w=self.frame.size.width/self.subviews.count;y=x=0;for(AMTabBarButton*btninself.subviews){btn.frame=CGRectMake(x,y,w,h);x+=w;}}

参数items:模型对象数组


当标签按钮被点击时发送代理方法:

-(void)itemBtnClicked:(AMTabBarButton*)sender{self.selectedBtn=sender;if(self.delegate&&[self.delegaterespondsToSelector:@selector(tabBarView:selectedIndex:)]){[self.delegatetabBarView:selfselectedIndex:sender.tag];}}-(void)setSelectedBtn:(AMTabBarButton*)selectedBtn{if(_selectedBtn!=selectedBtn){if(_selectedBtn!=nil){_selectedBtn.selected=NO;}_selectedBtn=selectedBtn;_selectedBtn.selected=YES;}}

其中selectBtn属性表示当前被选择的按钮


定义UITabBarController子类

添加属性:样式、标签栏、模型数组

@property(nonatomic,assign)AMTabBarStyletabBarStyle;@property(nonatomic,weak)AMTabBarView*myTabBar;@property(nonatomic,strong)NSArray*items;


添加创建控制器子类的方法:

+(instancetype)tabBarControllerWithItems:(NSArray*)itemstabBarStyle:(AMTabBarStyle)tabBarStyle{AMTabBarController*tabBarController=[[UIStoryboardstoryboardWithName:@"AMTabBarController"bundle:nil]instantiateInitialViewController];tabBarController.items=items;tabBarController.tabBarStyle=tabBarStyle;NSMutableArray*arr=[NSMutableArrayarray];for(AMTabBarItemModel*modelinitems){[arraddObject:model.viewController];model.viewController=nil;}tabBarController.viewControllers=[arrcopy];returntabBarController;}


创建自定义的标签栏,添加到tabBar视图上

-(void)viewDidLoad{[superviewDidLoad];//Doanyadditionalsetupafterloadingtheview.[selfsetupTabBar];}-(void)setupTabBar{AMTabBarView*myTabBar=[AMTabBarViewtabBarViewWithItemModels:self.itemstabBarStyle:self.tabBarStyle];self.myTabBar=myTabBar;[self.tabBaraddSubview:self.myTabBar];self.myTabBar.delegate=self;}-(void)viewDidLayoutSubviews{[superviewDidLayoutSubviews];self.myTabBar.frame=self.tabBar.bounds;}


实现自定义标签栏的代理方法,切换页面

-(void)tabBarView:(AMTabBarView*)tabBarViewselectedIndex:(NSInteger)index{self.selectedIndex=index-1;}