iOS自定義UITabBar

做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
對應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
基本組件代碼就是如上所述的,調用代碼如下:

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方法。另外沒經過實際項目測試等等。。。請大神們幫忙指正啦!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章