搞IOS开发的都知道,系统自带的UITabBar功能有限,默认的就是切换页面,那种弹出菜单啥的都不支持,而且可控制程度很低,样式修改也麻烦等等一堆问题。在经历了公司第一个项目那抹布一样的界面之后,决定将各组件全自定义一遍,不说多么花哨,但至少要看着顺眼。OK 开工
首先自定义一个控制器类 MyTabBarController,代码如下(包含了注释,将就看吧):
//
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
48
NSLog(@"%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
基本组件代码就是如上所述的,调用代码如下:
view sourceprint?
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方法(这问题可以修改,不过目前懒得动了),另外没经过实际项目测试等等。。。