• 自定义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;}