自定义UITabBarController子类
UITabBarController的tabBar往往不能满足我们的需求
通过自定义UITabBarController子类自定义标签栏是经常采用的方式。
基本步骤:
1)定义UIButton子类作为标签按钮
2)定义模型类,管理每个页面的控制器以及对应标签栏上的数据
3)自定义标签栏
4)定义UITabBarController子类
定义标签按钮
添加两种创建方法:只显示图片和文字图片都显示的
+ (AMTabBarButton *)tabBarButtonWithTitle:(NSString *)title normalImage:(UIImage *)normalImage selectedImage:(UIImage *)selectedImage { AMTabBarButton * btn = [AMTabBarButton buttonWithType:UIButtonTypeCustom]; [btn setImage:normalImage forState:UIControlStateNormal]; [btn setImage:selectedImage forState:UIControlStateSelected]; [btn setTitle:title forState:UIControlStateNormal]; [btn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal]; [btn setTitleColor:[UIColor orangeColor] forState:UIControlStateSelected]; btn.titleLabel.font = [UIFont systemFontOfSize:10]; btn.titleLabel.textAlignment = NSTextAlignmentCenter; return btn; } + (AMTabBarButton *)tabBarButtonWithNormalImage:(UIImage *)normalImage selectedImage:(UIImage *)selectedImage { AMTabBarButton * btn = [AMTabBarButton buttonWithType:UIButtonTypeCustom]; [btn setImage:normalImage forState:UIControlStateNormal]; [btn setImage:selectedImage forState:UIControlStateSelected]; [btn setTitle:nil forState:UIControlStateNormal]; return btn; }
修改按钮内部label和p_w_picpathView的位置,重写以下方法即可
- (CGRect)titleRectForContentRect:(CGRect)contentRect - (CGRect)p_w_picpathRectForContentRect:(CGRect)contentRect
如:
- (CGRect)p_w_picpathRectForContentRect:(CGRect)contentRect { CGFloat x, y, w, h; if ( [self titleForState: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; return CGRectMake(x, y, w, h); } - (CGRect)titleRectForContentRect:(CGRect)contentRect { CGFloat x, y, w, h; if ( [self titleForState:UIControlStateNormal] == nil ) { return CGRectZero; } h = contentRect.size.height*0.25; w = contentRect.size.width*0.6; x = contentRect.size.width*0.2; y = contentRect.size.height*0.65; return CGRectMake(x, y, w, h); }
取消按钮点击时的高亮效果:重写highlighted属性的setter方法
- (void)setHighlighted:(BOOL)highlighted { }
定义模型类
管理每个子控制器及标签栏上按钮的数据
@interface AMTabBarItemModel : NSObject @property (nonatomic, copy) UIImage * normalImage; @property (nonatomic, copy) UIImage * selectedImage; @property (nonatomic, copy) NSString * title; @property (nonatomic, strong) UIViewController * viewController; + (instancetype) tabBarItemModelWithNormalImage:(UIImage*) normalImage selectedImage:(UIImage*) selectedImage title:(NSString*) title viewController:(UIViewController*) viewController; @end
定义标签栏
定义一个UIView的子类作为自定义的标签类
设置样式属性,两种样式:只有图片和文字图片都有的
typedef enum { AMTabBarStyleTitleAndImage, AMTabBarStyleImageOnly }AMTabBarStyle;
创建方法:
+ (instancetype)tabBarViewWithItemModels:(NSArray *)models tabBarStyle:(AMTabBarStyle)tabBarStyle { return [[self alloc] initWithItemModels:models tabBarStyle:tabBarStyle]; } - (instancetype) initWithItemModels:(NSArray*) models tabBarStyle:(AMTabBarStyle) tabBarStyle { if ( self = [super init] ) { self.tabBarStyle = tabBarStyle; int i = 1; for ( AMTabBarItemModel * model in models ) { AMTabBarButton * btn; if ( tabBarStyle == AMTabBarStyleTitleAndImage ) { btn = [AMTabBarButton tabBarButtonWithTitle:model.title normalImage:model.normalImage selectedImage:model.selectedImage]; } else { btn = [AMTabBarButton tabBarButtonWithNormalImage:model.normalImage selectedImage:model.selectedImage]; } [self addSubview:btn]; [btn addTarget:self action:@selector(itemBtnClicked:) forControlEvents:UIControlEventTouchDown]; btn.tag = i; i++; } self.selectedBtn = self.subviews[0]; } return self; } - (void)layoutSubviews { [super layoutSubviews]; CGFloat x, y, w, h; h = self.frame.size.height; w = self.frame.size.width/self.subviews.count; y = x = 0; for ( AMTabBarButton * btn in self.subviews ) { btn.frame = CGRectMake(x, y, w, h); x += w; } }
参数items:模型对象数组
当标签按钮被点击时发送代理方法:
- (void) itemBtnClicked:(AMTabBarButton*) sender { self.selectedBtn = sender; if ( self.delegate && [self.delegate respondsToSelector:@selector(tabBarView:selectedIndex:)]) { [self.delegate tabBarView:self selectedIndex: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) AMTabBarStyle tabBarStyle; @property (nonatomic, weak) AMTabBarView * myTabBar; @property (nonatomic, strong) NSArray * items;
添加创建控制器子类的方法:
+ (instancetype)tabBarControllerWithItems:(NSArray *)items tabBarStyle:(AMTabBarStyle)tabBarStyle { AMTabBarController * tabBarController = [[UIStoryboard storyboardWithName:@"AMTabBarController" bundle:nil] instantiateInitialViewController]; tabBarController.items = items; tabBarController.tabBarStyle = tabBarStyle; NSMutableArray * arr = [NSMutableArray array]; for ( AMTabBarItemModel * model in items ) { [arr addObject:model.viewController]; model.viewController = nil; } tabBarController.viewControllers = [arr copy]; return tabBarController; }
创建自定义的标签栏,添加到tabBar视图上
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. [self setupTabBar]; } - (void) setupTabBar { AMTabBarView * myTabBar = [AMTabBarView tabBarViewWithItemModels:self.items tabBarStyle:self.tabBarStyle]; self.myTabBar = myTabBar; [self.tabBar addSubview:self.myTabBar]; self.myTabBar.delegate = self; } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; self.myTabBar.frame = self.tabBar.bounds; }
实现自定义标签栏的代理方法,切换页面
- (void)tabBarView:(AMTabBarView *)tabBarView selectedIndex:(NSInteger)index { self.selectedIndex = index-1; }
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。