做iOS開發的都知道,系統自帶的UITabBar功能有限,默認的就是切換頁面,類似彈出菜單一些功能都不支持,而且可控制程度很低,樣式修改也麻煩等等一堆問題。所以簡單小結一下相關知識。
首先自定義一個控制器類 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 |
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 |
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方法。另外沒經過實際項目測試等等。。。請大神們幫忙指正啦!