(转)IOS自定义UITabBar

来源:互联网 发布:调查问卷制作软件 编辑:程序博客网 时间:2024/05/23 16:11

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

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

01//
02//  MyTabBarViewController.h
03//  newIosMobile
04//
05//  Created by xoHome on 13-1-31.
06//  Copyright (c) 2013年 xoHome. All rights reserved.
07//
08 
09#import <UIKit/UIKit.h>
10#import "MyTabBar.h"
11#import "MyTabBarItem.h"
12 
13#define MyTabBarStyle int
14#define MyTabBarStyleViewController 1
15#define MyTabBarStyleClick 2
16 
17@interface MyTabBarController : UIViewController {
18    // UITabBar View
19    MyTabBar *tabBar;
20    // MainView, 包含BodyView和其它追加View
21    UIView *mainView;
22    // Body View
23    UIView *bodyView;
24     
25    // UIViewController集合
26    NSMutableArray *viewControllers;
27     
28    // 当前显示UIViewController下标
29    int selectedIndex;
30     
31    // 显示最大元素
32    int maxItems;
33     
34    // 回调delegate
35    id delegate;
36}
37 
38@property(nonatomic, readonly) MyTabBar *tabBar;
39@property(nonatomic, readonly) UIView *mainView;
40@property(nonatomic) int selectedIndex;
41@property(nonatomic, retain) id delegate;
42 
43// 根据类型添加视图,viewControllers集合为存放容器
44// tabBar数量最大值为maxItems
45- (void) addViewController:(UIViewController *)controller resource:(MyTabBarItem *)resource;
46 
47// 添加非Controller视图
48- (void) addEventTabItem:(MyTabBarItem *)resource;
49 
50// 添加完成,执行绘制
51- (void) addDone;
52 
53// 返回指定下标TabBar样式
54- (MyTabBarStyle) tabBarStyle:(int)index;
55 
56// 选择事件处理
57- (void) didSelectItem:(id)sender;
58 
59@end
60 
61@protocol MyTabBarControllerDelegate <NSObject>
62@optional
63- (void) myTabBarController:(MyTabBarController *)tabBarController didSelectViewController:(id)viewController index:(int)index;
64@end
对应m文件为:

001//
002//  MyTabBarViewController.m
003//  newIosMobile
004//  自定义UITabBar
005//  Created by xoHome on 13-1-31.
006//  Copyright (c) 2013年 xoHome. All rights reserved.
007//
008 
009#import "MyTabBarController.h"
010 
011@interface MyTabBarController ()
012 
013@end
014 
015@implementation MyTabBarController
016 
017@synthesize tabBar;
018@synthesize mainView;
019@synthesize selectedIndex;
020@synthesize delegate;
021 
022- (id) init {
023    self = [super init];
024     
025    selectedIndex = -1;
026    maxItems = 5;
027    viewControllers = [[NSMutableArray alloc] initWithCapacity:maxItems];
028     
029    self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
030     
031    tabBar = [[MyTabBar alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height - 49, self.view.frame.size.width, 49)];
032    tabBar.controller = self;
033     
034    mainView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - 49)];
035    [self.view addSubview:mainView];
036     
037    bodyView = [[UIView alloc] initWithFrame:mainView.frame];
038    [mainView addSubview:bodyView];
039     
040    [self.view addSubview:tabBar];
041     
042    return self;
043}
044 
045- (void) addDone {
046    // 生成UI
047    NSMutableArray *items = [[NSMutableArray alloc] initWithCapacity:viewControllers.count];
048    for(NSDictionary *item in viewControllers) {
049        [items addObject:[item objectForKey:@"resource"]];
050    }
051    [tabBar addTabItems:items];
052    [items release];
053     
054    // 默认显示第一项
055    for(int i=0; i<viewControllers.count; i++) {
056        if([[[viewControllers objectAtIndex:i] objectForKey:@"style"] intValue] == MyTabBarStyleViewController) {
057            [self didSelectItemByIndex:i];
058            break;
059        }
060    }
061}
062 
063- (void) addViewController:(UIViewController *)controller resource:(MyTabBarItem *)resource{
064    if(viewControllers.count >= maxItems) {
065        // 包含Controller数量达到规定maxItems则不操作
066        return;
067    }
068    [self addItem:controller resource:resource style:MyTabBarStyleViewController];
069}
070 
071- (void) addEventTabItem:(MyTabBarItem *)resource {
072    [self addItem:nil resource:resource style:MyTabBarStyleClick];
073}
074 
075// 添加视图公共方法
076- (void) addItem:(id)item resource:(MyTabBarItem *)resource style:(MyTabBarStyle)style {
077    id temp = item == nil ? [NSNull null] : item;
078    NSDictionary *tabItem = [NSDictionary dictionaryWithObjectsAndKeys:temp, @"controller", [NSNumber numberWithInt:style], @"style", resource, @"resource", nil];
079    [viewControllers addObject:tabItem];
080}
081 
082- (MyTabBarStyle) tabBarStyle:(int)index {
083    if(index >= viewControllers.count) {
084        return -1;
085    }
086    return [[[viewControllers objectAtIndex:index] objectForKey:@"style"] intValue];
087}
088 
089- (void) didSelectItem:(id)sender {
090    int index = [sender tag];
091    [self didSelectItemByIndex:index];
092}
093 
094- (void) didSelectItemByIndex:(int)index {
095    MyTabBarStyle style = [self tabBarStyle:index];
096    if(style == MyTabBarStyleViewController) {
097        [tabBar didSelectItem:index];
098        if(selectedIndex == index) {
099            return;
100        }
101        if(selectedIndex > -1) {
102            [[[[viewControllers objectAtIndex:selectedIndex] objectForKey:@"controller"] view] removeFromSuperview];
103        }
104        UIView *temp = [[[viewControllers objectAtIndex:index] objectForKey:@"controller"] view];
105        temp.frame = bodyView.frame;
106        [bodyView addSubview:temp];
107        selectedIndex = index;
108    }
109    // 回调delegate
110    if([delegate respondsToSelector:@selector(myTabBarController:didSelectViewController:index:)]) {
111        [delegate myTabBarController:self didSelectViewController:[[viewControllers objectAtIndex:selectedIndex]objectForKey:@"controller"] index:index];
112    }
113}
114 
115- (void) dealloc {
116    [super dealloc];
117    [tabBar release];
118    [mainView release];
119    [bodyView release];
120    [viewControllers release];
121    [delegate release];
122}
123 
124- (void)didReceiveMemoryWarning
125{
126    [super didReceiveMemoryWarning];
127}
128 
129@end

UI组件MyTabBar文件如下:

01//
02//  MyTabBar.h
03//  newIosMobile
04//
05//  Created by xoHome on 13-1-31.
06//  Copyright (c) 2013年 xoHome. All rights reserved.
07//
08 
09#import <UIKit/UIKit.h>
10 
11@interface MyTabBar : UIView {
12    // Background View
13    UIImageView *backgroundView;
14     
15    // TabItem控件集合
16    NSMutableArray *tabItems;
17    // resource集合
18    NSArray *resources;
19     
20    // delegate
21    id controller;
22}
23 
24@property(nonatomic, retain)id controller;
25@property(nonatomic, readonly)UIImageView *backgroundView;
26 
27// 添加TabItems
28- (void) addTabItems:(NSArray *)items;
29 
30- (void) didSelectItem:(int)index;
31 
32@end
01//
02//  MyTabBar.m
03//  newIosMobile
04//
05//  Created by xoHome on 13-1-31.
06//  Copyright (c) 2013年 xoHome. All rights reserved.
07//
08 
09#import "MyTabBar.h"
10#import "MyTabBarController.h"
11#import "MyTabBarItemView.h"
12 
13@implementation MyTabBar
14 
15@synthesize controller;
16@synthesize backgroundView;
17 
18- (id)initWithFrame:(CGRect)frame
19{
20    self = [super initWithFrame:frame];
21     
22    backgroundView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
23    [backgroundView setBackgroundColor:[UIColor blackColor]];
24    [self addSubview:backgroundView];
25     
26    tabItems = [[NSMutableArray alloc] initWithCapacity:5];
27     
28    return self;
29}
30 
31- (void) addTabItems:(NSArray *)items {
32    resources = [items retain];
33    float width = self.frame.size.width / resources.count;
34    int index = 0;
35    for(MyTabBarItem *item in resources) {
36        /*
37        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
38        btn.showsTouchWhenHighlighted = YES;
39        btn.tag = index;
40         
41        btn.frame = CGRectMake(width * index, 0, width, self.frame.size.height);
42         
43        [btn.titleLabel setFont:[UIFont systemFontOfSize:13]];
44        [btn setImage:item.iDefault forState:UIControlStateNormal];
45        [btn setImage:item.iHighlighted forState:UIControlStateHighlighted];
46        [btn setImage:item.iSeleted forState:UIControlStateSelected];
47         
48NSLog(@"%f", btn.imageView.frame.size.width);
49        [btn setTitle:item.text forState:UIControlStateNormal];
50         
51        [btn addTarget:controller action:@selector(didSelectItem:) forControlEvents:UIControlEventTouchUpInside];
52        [tabItems addObject:btn];
53        [self addSubview:btn];*/
54        MyTabBarItemView *btn = [[MyTabBarItemView alloc] initWithImage:item.iDefault text:item.text frame:CGRectMake(width * index, 0, width, self.frame.size.height) deletage:controller];
55        btn.button.tag = index;
56        [tabItems addObject:btn];
57        [self addSubview:btn];
58        [btn release];
59        index ++;
60    }
61}
62 
63- (void) dealloc {
64    [super dealloc];
65    [backgroundView release];
66    [tabItems release];
67    [controller release];
68    [resources release];
69}
70 
71- (void) didSelectItem:(int)index {
72    for (int i = 0; i < tabItems.count; i++)
73    {
74        MyTabBarItemView *btn = [tabItems objectAtIndex:i];
75        MyTabBarItem *item = [resources objectAtIndex:i];
76        if(i != index) {
77            [btn.imageView setImage:item.iDefault];
78            btn.userInteractionEnabled = YES;
79            [btn setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"bg.png"]]];
80        else {
81            [btn.imageView setImage:item.iHighlighted];
82            btn.userInteractionEnabled = NO;
83            [btn setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"selectedbg.png"]]];
84        }
85    }
86}
87 
88@end
对于UIBarItem元素,我本来是打算用UIButton组件的,但UIButton对图片的控制不方便(比如大小位置等),所以自定义了一个  MyTabBarItemView

01//
02//  MyTabBarItemView.h
03//  newIosMobile
04//
05//  Created by xoHome on 13-2-1.
06//  Copyright (c) 2013年 xoHome. All rights reserved.
07//
08 
09#import <UIKit/UIKit.h>
10 
11@interface MyTabBarItemView : UIView {
12    // 按钮
13    UIButton *button;
14     
15    // 图片
16    UIImageView *imageView;
17     
18    // 文字
19    UILabel *txt;
20}
21 
22@property(nonatomic, readonly) UIImageView *imageView;
23@property(nonatomic, readonly) UILabel *txt;
24@property(nonatomic, readonly) UIButton *button;
25 
26- (id) initWithImage:(UIImage *)image text:(NSString *)text frame:(CGRect)frame deletage:(id)delegate;
27 
28@end
01//
02//  MyTabBarItemView.m
03//  newIosMobile
04//
05//  Created by xoHome on 13-2-1.
06//  Copyright (c) 2013年 xoHome. All rights reserved.
07//
08 
09#import "MyTabBarItemView.h"
10 
11@implementation MyTabBarItemView
12 
13@synthesize imageView;
14@synthesize txt;
15@synthesize button;
16 
17- (id) initWithImage:(UIImage *)image text:(NSString *)text frame:(CGRect)frame deletage:(id)delegate {
18    self = [super initWithFrame:frame];
19     
20    [self setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"bg.png"]]];
21     
22    imageView = [[UIImageView alloc] initWithFrame:CGRectMake(frame.size.width/2-15, 7, 30, frame.size.height-25)];
23    [imageView setImage:image];
24    [self addSubview:imageView];
25     
26    UIFont *font = [UIFont systemFontOfSize:12];
27    txt = [[UILabel alloc] initWithFrame:CGRectMake(frame.size.width/2-[text sizeWithFont:font].width/2, frame.size.height - 16, [text sizeWithFont:font].width, 15)];
28    [txt setFont:[UIFont systemFontOfSize:12]];
29    [txt setBackgroundColor:[UIColor clearColor]];
30    [txt setTextColor:[UIColor whiteColor]];
31    [txt setText:text];
32    [self addSubview:txt];
33     
34    button = [UIButton buttonWithType:UIButtonTypeCustom];
35    button.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);
36    [button setBackgroundColor:[UIColor clearColor]];
37    button.showsTouchWhenHighlighted = YES;
38    [button addTarget:delegate action:@selector(didSelectItem:) forControlEvents:UIControlEventTouchUpInside];
39    [self addSubview:button];
40     
41    return self;
42}
43 
44- (void) dealloc {
45    [super dealloc];
46    [button release];
47    [imageView release];
48    [txt release];
49}
50 
51@end
基本组件代码就是如上所述的,调用代码如下:

01//
02//  ViewController.m
03//  newIosMobile
04//
05//  Created by xoHome on 13-1-31.
06//  Copyright (c) 2013年 xoHome. All rights reserved.
07//
08 
09#import "ViewController.h"
10#import "IndexViewController.h"
11 
12@interface ViewController ()
13 
14@end
15 
16@implementation ViewController
17 
18- (void)viewDidLoad
19{
20    [super viewDidLoad];
21     
22    tabbar = [[MyTabBarController alloc] init];
23    [tabbar.view setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
24    tabbar.delegate = self;
25    //tabbar.tabBar.backgroundView.image = [UIImage imageNamed:@"Table_Bar.png"];
26     
27    IndexViewController *one = [[IndexViewController alloc] init];
28    [one.view setBackgroundColor:[UIColor redColor]];
29     
30    IndexViewController *two = [[IndexViewController alloc] init];
31    [two.view setBackgroundColor:[UIColor blueColor]];
32     
33    IndexViewController *three = [[IndexViewController alloc] init];
34    [three.view setBackgroundColor:[UIColor yellowColor]];
35     
36    [tabbar addViewController:one resource:MyTabBarItemMake([UIImage imageNamed:@"xianhuo.png"], [UIImage imageNamed:@"xianhuo_click.png"], [UIImage imageNamed:@"xianhuo_click.png"], @"现货")];
37    [tabbar addViewController:two resource:MyTabBarItemMake([UIImage imageNamed:@"zixun.png"], [UIImage imageNamed:@"zixun_click.png"], [UIImage imageNamed:@"zixun_click.png"], @"资讯")];
38    [tabbar addViewController:three resource:MyTabBarItemMake([UIImage imageNamed:@"qihuo.png"], [UIImage imageNamed:@"qihuo_click.png"], [UIImage imageNamed:@"qihuo_click.png"], @"期货")];
39    [tabbar addEventTabItem:MyTabBarItemMake([UIImage imageNamed:@"more.png"], [UIImage imageNamed:@"more_click.png"], nil, @"更多")];
40     
41    [tabbar addDone];
42     
43    [self.view addSubview:tabbar.view];
44}
45 
46// MyTabBarController的回调方法
47- (void) myTabBarController:(MyTabBarController *)tabBarController didSelectViewController:(id)viewController index:(int)index {
48    if(index == 3) {
49        if(toolView == nil) {
50            toolView = [[UIView alloc] initWithFrame:CGRectMake(0, tabbar.mainView.frame.size.height, tabbar.mainView.frame.size.width, 100)];
51            [toolView setBackgroundColor:[UIColor scrollViewTexturedBackgroundColor]];
52            [tabbar.mainView addSubview:toolView];
53            [toolView setAlpha:0];
54        }
55        [UIView beginAnimations:nil context:nil];
56         
57        if(toolView.frame.origin.y >= tabbar.mainView.frame.size.height) {
58            [toolView setAlpha:1];
59            toolView.frame = CGRectMake(0, tabbar.mainView.frame.size.height - 100, tabbar.mainView.frame.size.width, 100);
60        else {
61            [toolView setAlpha:0];
62            toolView.frame = CGRectMake(0, tabbar.mainView.frame.size.height, tabbar.mainView.frame.size.width, 100);
63        }
64        [UIView commitAnimations];
65    }
66}
67 
68- (void)didReceiveMemoryWarning
69{
70    [super didReceiveMemoryWarning];
71    // Dispose of any resources that can be recreated.
72}
73 
74- (void) dealloc {
75    [super dealloc];
76    [tabbar release];
77    [toolView release];
78}
79 
80@end

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



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

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



0 0