IOS自定义UITabBar

搞IOS开发的都知道,系统自带的UITabBar功能有限,默认的就是切换页面,那种弹出菜单啥的都不支持,而且可控制程度很低,样式修改也麻烦等等一堆问题。在经历了公司第一个项目那抹布一样的界面之后,决定将各组件全自定义一遍,不说多么花哨,但至少要看着顺眼。OK 开工

首先自定义一个控制器类 MyTabBarController,代码如下(包含了注释,将就看吧):

//
//  MyTabBarViewController.h
//  newIosMobile
//
//  Created by xoHome on 13-1-31.
//  Copyright (c) 2013年 xoHome. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "MyTabBar.h"
#import "MyTabBarItem.h"

#define MyTabBarStyle int
#define MyTabBarStyleViewController 1
#define MyTabBarStyleClick 2

@interface MyTabBarController : UIViewController {
    // UITabBar View
    MyTabBar *tabBar;
    // MainView, 包含BodyView和其它追加View
    UIView *mainView;
    // Body View
    UIView *bodyView;
    
    // UIViewController集合
    NSMutableArray *viewControllers;
    
    // 当前显示UIViewController下标
    int selectedIndex;
    
    // 显示最大元素
    int maxItems;
    
    // 回调delegate
    id delegate;
}

@property(nonatomic, readonly) MyTabBar *tabBar;
@property(nonatomic, readonly) UIView *mainView;
@property(nonatomic) int selectedIndex;
@property(nonatomic, retain) id delegate;

// 根据类型添加视图,viewControllers集合为存放容器
// tabBar数量最大值为maxItems
- (void) addViewController:(UIViewController *)controller resource:(MyTabBarItem *)resource;

// 添加非Controller视图
- (void) addEventTabItem:(MyTabBarItem *)resource;

// 添加完成,执行绘制
- (void) addDone;

// 返回指定下标TabBar样式
- (MyTabBarStyle) tabBarStyle:(int)index;

// 选择事件处理
- (void) didSelectItem:(id)sender;

@end

@protocol MyTabBarControllerDelegate <NSObject>
@optional
- (void) myTabBarController:(MyTabBarController *)tabBarController didSelectViewController:(id)viewController index:(int)index;
@end
对应m文件为:

//
//  MyTabBarViewController.m
//  newIosMobile
//  自定义UITabBar
//  Created by xoHome on 13-1-31.
//  Copyright (c) 2013年 xoHome. All rights reserved.
//

#import "MyTabBarController.h"

@interface MyTabBarController ()

@end

@implementation MyTabBarController

@synthesize tabBar;
@synthesize mainView;
@synthesize selectedIndex;
@synthesize delegate;

- (id) init {
    self = [super init];
    
    selectedIndex = -1;
    maxItems = 5;
    viewControllers = [[NSMutableArray alloc] initWithCapacity:maxItems];
    
    self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
    
    tabBar = [[MyTabBar alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height - 49, self.view.frame.size.width, 49)];
    tabBar.controller = self;
    
    mainView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - 49)];
    [self.view addSubview:mainView];
    
    bodyView = [[UIView alloc] initWithFrame:mainView.frame];
    [mainView addSubview:bodyView];
    
    [self.view addSubview:tabBar];
    
    return self;
}

- (void) addDone {
    // 生成UI
    NSMutableArray *items = [[NSMutableArray alloc] initWithCapacity:viewControllers.count];
    for(NSDictionary *item in viewControllers) {
        [items addObject:[item objectForKey:@"resource"]];
    }
    [tabBar addTabItems:items];
    [items release];
    
    // 默认显示第一项
    for(int i=0; i<viewControllers.count; i++) {
        if([[[viewControllers objectAtIndex:i] objectForKey:@"style"] intValue] == MyTabBarStyleViewController) {
            [self didSelectItemByIndex:i];
            break;
        }
    }
}

- (void) addViewController:(UIViewController *)controller resource:(MyTabBarItem *)resource{
    if(viewControllers.count >= maxItems) {
        // 包含Controller数量达到规定maxItems则不操作
        return;
    }
    [self addItem:controller resource:resource style:MyTabBarStyleViewController];
}

- (void) addEventTabItem:(MyTabBarItem *)resource {
    [self addItem:nil resource:resource style:MyTabBarStyleClick];
}

// 添加视图公共方法
- (void) addItem:(id)item resource:(MyTabBarItem *)resource style:(MyTabBarStyle)style {
    id temp = item == nil ? [NSNull null] : item;
    NSDictionary *tabItem = [NSDictionary dictionaryWithObjectsAndKeys:temp, @"controller", [NSNumber numberWithInt:style], @"style", resource, @"resource", nil];
    [viewControllers addObject:tabItem];
}

- (MyTabBarStyle) tabBarStyle:(int)index {
    if(index >= viewControllers.count) {
        return -1;
    }
    return [[[viewControllers objectAtIndex:index] objectForKey:@"style"] intValue];
}

- (void) didSelectItem:(id)sender {
    int index = [sender tag];
    [self didSelectItemByIndex:index];
}

- (void) didSelectItemByIndex:(int)index {
    MyTabBarStyle style = [self tabBarStyle:index];
    if(style == MyTabBarStyleViewController) {
        [tabBar didSelectItem:index];
        if(selectedIndex == index) {
            return;
        }
        if(selectedIndex > -1) {
            [[[[viewControllers objectAtIndex:selectedIndex] objectForKey:@"controller"] view] removeFromSuperview];
        }
        UIView *temp = [[[viewControllers objectAtIndex:index] objectForKey:@"controller"] view];
        temp.frame = bodyView.frame;
        [bodyView addSubview:temp];
        selectedIndex = index;
    }
    // 回调delegate
    if([delegate respondsToSelector:@selector(myTabBarController:didSelectViewController:index:)]) {
        [delegate myTabBarController:self didSelectViewController:[[viewControllers objectAtIndex:selectedIndex]objectForKey:@"controller"] index:index];
    }
}

- (void) dealloc {
    [super dealloc];
    [tabBar release];
    [mainView release];
    [bodyView release];
    [viewControllers release];
    [delegate release];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

@end

UI组件MyTabBar文件如下:

//
//  MyTabBar.h
//  newIosMobile
//
//  Created by xoHome on 13-1-31.
//  Copyright (c) 2013年 xoHome. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface MyTabBar : UIView {
    // Background View
    UIImageView *backgroundView;
    
    // TabItem控件集合
    NSMutableArray *tabItems;
    // resource集合
    NSArray *resources;
    
    // delegate
    id controller;
}

@property(nonatomic, retain)id controller;
@property(nonatomic, readonly)UIImageView *backgroundView;

// 添加TabItems
- (void) addTabItems:(NSArray *)items;

- (void) didSelectItem:(int)index;

@end
//
//  MyTabBar.m
//  newIosMobile
//
//  Created by xoHome on 13-1-31.
//  Copyright (c) 2013年 xoHome. All rights reserved.
//

#import "MyTabBar.h"
#import "MyTabBarController.h"
#import "MyTabBarItemView.h"

@implementation MyTabBar

@synthesize controller;
@synthesize backgroundView;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    
    backgroundView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    [backgroundView setBackgroundColor:[UIColor blackColor]];
    [self addSubview:backgroundView];
    
    tabItems = [[NSMutableArray alloc] initWithCapacity:5];
    
    return self;
}

- (void) addTabItems:(NSArray *)items {
    resources = [items retain];
    float width = self.frame.size.width / resources.count;
    int index = 0;
    for(MyTabBarItem *item in resources) {
        /*
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        btn.showsTouchWhenHighlighted = YES;
        btn.tag = index;
        
        btn.frame = CGRectMake(width * index, 0, width, self.frame.size.height);
        
        [btn.titleLabel setFont:[UIFont systemFontOfSize:13]];
        [btn setImage:item.iDefault forState:UIControlStateNormal];
        [btn setImage:item.iHighlighted forState:UIControlStateHighlighted];
        [btn setImage:item.iSeleted forState:UIControlStateSelected];
        
NSLog(@"%f", btn.imageView.frame.size.width);
        [btn setTitle:item.text forState:UIControlStateNormal];
        
        [btn addTarget:controller action:@selector(didSelectItem:) forControlEvents:UIControlEventTouchUpInside];
        [tabItems addObject:btn];
        [self addSubview:btn];*/
        MyTabBarItemView *btn = [[MyTabBarItemView alloc] initWithImage:item.iDefault text:item.text frame:CGRectMake(width * index, 0, width, self.frame.size.height) deletage:controller];
        btn.button.tag = index;
        [tabItems addObject:btn];
        [self addSubview:btn];
        [btn release];
        index ++;
    }
}

- (void) dealloc {
    [super dealloc];
    [backgroundView release];
    [tabItems release];
    [controller release];
    [resources release];
}

- (void) didSelectItem:(int)index {
    for (int i = 0; i < tabItems.count; i++)
	{
        MyTabBarItemView *btn = [tabItems objectAtIndex:i];
        MyTabBarItem *item = [resources objectAtIndex:i];
        if(i != index) {
            [btn.imageView setImage:item.iDefault];
            btn.userInteractionEnabled = YES;
            [btn setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"bg.png"]]];
        } else {
            [btn.imageView setImage:item.iHighlighted];
            btn.userInteractionEnabled = NO;
            [btn setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"selectedbg.png"]]];
        }
	}
}

@end
对于UIBarItem元素,我本来是打算用UIButton组件的,但UIButton对图片的控制不方便(比如大小位置等),所以自定义了一个  MyTabBarItemView

//
//  MyTabBarItemView.h
//  newIosMobile
//
//  Created by xoHome on 13-2-1.
//  Copyright (c) 2013年 xoHome. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface MyTabBarItemView : UIView {
    // 按钮
    UIButton *button;
    
    // 图片
    UIImageView *imageView;
    
    // 文字
    UILabel *txt;
}

@property(nonatomic, readonly) UIImageView *imageView;
@property(nonatomic, readonly) UILabel *txt;
@property(nonatomic, readonly) UIButton *button;

- (id) initWithImage:(UIImage *)image text:(NSString *)text frame:(CGRect)frame deletage:(id)delegate;

@end
//
//  MyTabBarItemView.m
//  newIosMobile
//
//  Created by xoHome on 13-2-1.
//  Copyright (c) 2013年 xoHome. All rights reserved.
//

#import "MyTabBarItemView.h"

@implementation MyTabBarItemView

@synthesize imageView;
@synthesize txt;
@synthesize button;

- (id) initWithImage:(UIImage *)image text:(NSString *)text frame:(CGRect)frame deletage:(id)delegate {
    self = [super initWithFrame:frame];
    
    [self setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"bg.png"]]];
    
    imageView = [[UIImageView alloc] initWithFrame:CGRectMake(frame.size.width/2-15, 7, 30, frame.size.height-25)];
    [imageView setImage:image];
    [self addSubview:imageView];
    
    UIFont *font = [UIFont systemFontOfSize:12];
    txt = [[UILabel alloc] initWithFrame:CGRectMake(frame.size.width/2-[text sizeWithFont:font].width/2, frame.size.height - 16, [text sizeWithFont:font].width, 15)];
    [txt setFont:[UIFont systemFontOfSize:12]];
    [txt setBackgroundColor:[UIColor clearColor]];
    [txt setTextColor:[UIColor whiteColor]];
    [txt setText:text];
    [self addSubview:txt];
    
    button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);
    [button setBackgroundColor:[UIColor clearColor]];
    button.showsTouchWhenHighlighted = YES;
    [button addTarget:delegate action:@selector(didSelectItem:) forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:button];
    
    return self;
}

- (void) dealloc {
    [super dealloc];
    [button release];
    [imageView release];
    [txt release];
}

@end
基本组件代码就是如上所述的,调用代码如下:

//
//  ViewController.m
//  newIosMobile
//
//  Created by xoHome on 13-1-31.
//  Copyright (c) 2013年 xoHome. All rights reserved.
//

#import "ViewController.h"
#import "IndexViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
	
    tabbar = [[MyTabBarController alloc] init];
    [tabbar.view setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    tabbar.delegate = self;
    //tabbar.tabBar.backgroundView.image = [UIImage imageNamed:@"Table_Bar.png"];
    
    IndexViewController *one = [[IndexViewController alloc] init];
    [one.view setBackgroundColor:[UIColor redColor]];
    
    IndexViewController *two = [[IndexViewController alloc] init];
    [two.view setBackgroundColor:[UIColor blueColor]];
    
    IndexViewController *three = [[IndexViewController alloc] init];
    [three.view setBackgroundColor:[UIColor yellowColor]];
    
    [tabbar addViewController:one resource:MyTabBarItemMake([UIImage imageNamed:@"xianhuo.png"], [UIImage imageNamed:@"xianhuo_click.png"], [UIImage imageNamed:@"xianhuo_click.png"], @"现货")];
    [tabbar addViewController:two resource:MyTabBarItemMake([UIImage imageNamed:@"zixun.png"], [UIImage imageNamed:@"zixun_click.png"], [UIImage imageNamed:@"zixun_click.png"], @"资讯")];
    [tabbar addViewController:three resource:MyTabBarItemMake([UIImage imageNamed:@"qihuo.png"], [UIImage imageNamed:@"qihuo_click.png"], [UIImage imageNamed:@"qihuo_click.png"], @"期货")];
    [tabbar addEventTabItem:MyTabBarItemMake([UIImage imageNamed:@"more.png"], [UIImage imageNamed:@"more_click.png"], nil, @"更多")];
    
    [tabbar addDone];
    
    [self.view addSubview:tabbar.view];
}

// MyTabBarController的回调方法
- (void) myTabBarController:(MyTabBarController *)tabBarController didSelectViewController:(id)viewController index:(int)index {
    if(index == 3) {
        if(toolView == nil) {
            toolView = [[UIView alloc] initWithFrame:CGRectMake(0, tabbar.mainView.frame.size.height, tabbar.mainView.frame.size.width, 100)];
            [toolView setBackgroundColor:[UIColor scrollViewTexturedBackgroundColor]];
            [tabbar.mainView addSubview:toolView];
            [toolView setAlpha:0];
        }
        [UIView beginAnimations:nil context:nil];
        
        if(toolView.frame.origin.y >= tabbar.mainView.frame.size.height) {
            [toolView setAlpha:1];
            toolView.frame = CGRectMake(0, tabbar.mainView.frame.size.height - 100, tabbar.mainView.frame.size.width, 100);
        } else {
            [toolView setAlpha:0];
            toolView.frame = CGRectMake(0, tabbar.mainView.frame.size.height, tabbar.mainView.frame.size.width, 100);
        }
        [UIView commitAnimations];
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void) dealloc {
    [super dealloc];
    [tabbar release];
    [toolView release];
}

@end

给个预览图看看(因为素材不是很高清,所以有点模糊,这个换图片就可以了):

IOS自定义UITabBar

IOS自定义UITabBar

前三项为普通的页面切换,最后一项为自定义功能的选项,主要处理代码写在MyTabBarController的protocol回调方法中。

目前该组件还有些问题,比如:为了调用方便,为了一个个添加UIViewController而不是像系统自带的一次性添加一个数组,最后必须调用addDone方法(这问题可以修改,不过目前懒得动了),另外没经过实际项目测试等等。。。

你可能感兴趣的:(ios,自定义,uitabbar)