續前)
第七步:UINavigationItem和UIBarButtonItem
通常每個(指任何)視圖控制器都可以定義一個UINavigationItem。UINavigationItem類就是實現這些功能的,這個類包含了如下表:
左邊按鈕
標題視圖
右邊按鈕
leftBarButtonItem
titleView
rightBarButtonItem
當它所屬的視圖控制器在導航控制器所控制的堆棧頂部時,即調用(也就是說該視圖控制器即將要顯示時),系統自動顯示該視圖控制器的UINavigationItem,開發人員無需編寫任何代碼來調用UINavigationItem,但之前必須要設置好。上面程序代碼中已經有定制好的導航欄左右按鈕,簡述說明如下:
定制返回按鈕:在缺省情況下,下一頁上的返回按鈕上的文字是上一頁的標題,可以在程序中修改為其它文字,要記住!返回按鈕是放在上一頁的視圖控制器上的,所以必須在上一頁對應的視圖控制器的實現文件(*.m)中去修改。如在上面lvyouAppDelegate.m中有如下代碼:(圖中綠色代碼部分)
[plain]
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
……
navController = [[UINavigationController alloc] init];//初始化導航控制器
//定義名稱為“所有城市”的返回按鈕。該按鈕無需target和action
//因為系統已經實現了返回功能。Style是顯示風格
UIBarButtonItem *backButton =
[[UIBarButtonItem alloc] initWithTitle:@"所有城市"
style:UIBarButtonItemStyleBordered
target:nil action:nil];
//設置啟動應用時第一個要顯示的視圖控制器,這裡是cityViewContrl
cityViewController *cityViewContrl = [[cityViewController alloc] init];
cityViewContrl.title = @"旅游指南";//設置第一個視圖控制器的標題
//設置返回按鈕
cityViewContrl.navigationItem.backBarButtonItem= backButton;
[backButton release];
//把第一個視圖控制器推push到堆棧中
[navController pushViewController:cityViewContrl animated:NO];
[cityViewContrl release];
//把導航(標簽欄)控制器放到Window下
//[window addSubview:navController.view];
[window addSubview:tabBarController.view];
// Override point for customization after application launch.
[window makeKeyAndVisible];
return YES;
}
在導航控制欄上添加系統按鈕和左右按鈕。
首先在第一頁的導航欄上添加一個“折扣信息”按鈕,如在上面所述,要記住!返回按鈕是放在上一頁的視圖控制器上的,所以必須在上一頁對應的視圖控制器的實現文件(*.m)中去修改。這裡要求在第一頁的導航欄上添加一個“折扣信息”按鈕(顯然,這不是返回上一頁按鈕,而是在導航控制欄上添加一個“左按鈕”),故可在當前視圖控制器的實現文件(*.m)中去修改,即cityViewController.m中去修改,在它原代碼中有如下代碼:(圖中綠色代碼部分)
[plain]
- (void)viewDidLoad {
//創建一個有邊框的文體按鈕,按下後,調用視圖控制器上的discount方法
UIBarButtonItem *discountButton = [[UIBarButtonItem alloc]
initWithTitle:@"折扣信息" style:UIBarButtonItemStyleBordered
target:self action:@selector(discount:)];
self.navigationItem.leftBarButtonItem = discountButton;//設置為左邊按鈕
[discountButton release];//釋放內存
UITabBarItem *item = [[UITabBarItem alloc]
initWithTitle:@"旅游指南"
//initWithTabBarSystemItem:UITabBarSystemItemBookmarks
image:[UIImage imageNamed:@"GoldenGateBridge.png"]
tag:0];
self.tabBarItem = item;
[item release];
[super viewDidLoad];
}
其次在第二頁的導航欄上添加一個“系統按鈕”(右邊按鈕),根據上面分析,這同樣不以至於返回按鈕,故可在當前視圖控制器的實現文件(*.m)中去修改,即CityDetailViewController.m中去修改,在它原代碼中有如下代碼:(圖中綠色代碼部分)
[plain]
- (void)viewDidLoad {
cityName.text = city;//獲取從前一個頁面傳來的數據
//創建一個系統添加按鈕,按下後,調用視圖控制器上的add方法
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self action:@selector(add:)];// 調用視圖控制器上的add方法
//設置為導航控制器控制條上的右邊按鈕
self.navigationItem.rightBarButtonItem = rightButton;
[rightButton release];
[super viewDidLoad];
}
第八步:標簽欄控制器(UITabBarController)
標簽欄控制器是用數組來管理所控制的視圖控制器。這些被管理的視圖控制器即可以是導航控制器,也可以是一般的視圖控制器。另外,這些視圖控制器之間是平等關系,而不像導航控制器所管理的視圖控制器之間是所謂的“上下級關系”。缺省情況下,標簽欄上顯示的是各個視圖的標題,如下圖顯示了五個標簽。
iPhone OS的標簽欄最多可顯示五個標簽
當你選擇某一個視圖控制器時,該視圖控制器就執行。當你選擇另一個視圖控制器時,當前視圖控制器的狀態被保留。非常類似微軟中的多窗口的概念。
關系: 平等關系 上、下級之間關系
標簽欄控制器
UITabBarController
導航控制器
(旅游信息)
一般視圖控制器
cityViewController
一般視圖控制器
CityDetailViewController
一般視圖控制器
(美食天地)
MeiShiTianDi
下面我們將創建一個標簽欄控制器,如上表,它有兩個標簽“旅游信息”和“美食天地”。“旅游信息”由於前面已經完成,它管理著兩個視圖控制器(cityViewController、 CityDetailViewController),因此,下面重點講解未完成的工件。
1、項目的委托AppDelegate聲明注冊一個標簽控制器、初始化後放到主窗口Window下
首先:因為項目名稱仍然是lvyou,所以要在項目.h中(lvyouAppDelegate.h)聲明一個標簽控制器:
[plain]
//lvyouAppDelegate.h原代碼開始
#import <UIKit/UIKit.h>
@interface lvyouAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UINavigationController *navController;//此行新加,對應的實現文件.m上必須要有代碼!
UITabBarController *tabBarController;// 聲明一個標簽控制器
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@end
//lvyouAppDelegate.h原代碼結束
其次:要在項目.m中(lvyouAppDelegate.m)初始化,並將所要管理的控制器(本例是兩個:一個導航控制器、另一個是美食天地視圖控制器)放到其viewControllers數組中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
tabBarController = [[UITabBarController alloc] init];//初始化標簽欄控制器
MeiShiTianDi *viewController =[[MeiShiTianDi alloc] init];//初始化控制器
viewController.title=@"美食天地";
navController = [[UINavigationController alloc] init];//初始化導航控制器
//加入標簽欄控制器的控制器數量矩陣
//本例為兩個控制器navController viewController
tabBarController.viewControllers =
[NSArray arrayWithObjects:navController, viewController,nil];
[viewController release];//因它不是第一個視圖控制器,故釋放內存
//定義名稱為“所有城市”的返回按鈕。該按鈕無需target和action
//因為系統已經實現了返回功能。Style是顯示風格
UIBarButtonItem *backButton =
[[UIBarButtonItem alloc] initWithTitle:@"所有城市"
style:UIBarButtonItemStyleBordered
target:nil action:nil];
//設置啟動應用時第一個要顯示的視圖控制器,這裡是cityViewContrl
cityViewController *cityViewContrl = [[cityViewController alloc] init];
cityViewContrl.title = @"旅游指南";//設置第一個視圖控制器的標題
//設置返回按鈕
cityViewContrl.navigationItem.backBarButtonItem= backButton;
[backButton release];
//把第一個視圖控制器推push到堆棧中
[navController pushViewController:cityViewContrl animated:NO];
//這裡假定是導航欄的第一個視圖,所以animated:NO不要動畫化。
[cityViewContrl release];
//把導航(標簽欄)控制器放到Window下
//[window addSubview:navController.view];
[window addSubview:tabBarController.view]; //把標簽欄控制器放到Window下
// Override point for customization after application launch.
[window makeKeyAndVisible];
return YES;
}
2、創建另一個(第三個)視圖控制器——美食天地:MeiShiTianDi
方法同前:
>>請選擇File > New File。在New File窗口中,請選擇Cocoa Touch Classes,然後選擇UIViewController-subclass。同時,請勾選Options區域中標題為With XIB for user interface的選擇框。為文件起個名字,視圖控制器名稱為MeiShiTianDi。此時,系統已經生成三個文件(*.h、*.m、*.xib),在新的視圖控制器的視圖上(MeiShiTianDi.xib)添加一些按鈕(加四個,命名為“廣東菜、浙江菜、四川菜、東北菜”)。
1)、添加標簽欄控制器的屬性到lvyouAppDelegate.h中——(上一步已經完成!)
2)、在lvyouAppDelegate.m文件中的- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法中,用代碼方式創建一個標簽欄控制器,並初始化它,最後將兩個控制器navController(旅游信息)、viewController(美食天地)放在標簽控制器上。——(上一步已經完成!)
[plain]
//MeiShiTianDi.h原代碼開始
#import <UIKit/UIKit.h>
@interface MeiShiTianDi : UIViewController {
}
@end
//MeiShiTianDi.m原代碼結束
//MeiShiTianDi.h原代碼開始
#import "MeiShiTianDi.h"
@implementation MeiShiTianDi
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
//UIImage *tabImage = [UIImage imageNamed:@"shrimp.jpg"];
//設置視圖控制器在標簽欄上的標題和圖像
// 文字是:美食天地。圖像是:UITabBarSystemItemBookmarks
UITabBarItem *item = [[UITabBarItem alloc]
initWithTitle:@"美食天地"
initWithTabBarSystemItem:UITabBarSystemItemBookmarks
//image:tabImage
tag:0];
//本例還注釋掉了使用自己的圖像shrimp.jpg的兩行代碼。如你交換一下也能運行
self.tabBarItem = item;
[item release];
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
@end
//MeiShiTianDi.m原代碼結束
3)、設置視圖控制器在標簽欄上的標題和圖像(UITabBarItem)
每個視圖控制器類都有一個UITabBarItem。通過這個類,可以設置視圖控制器在標簽欄上的標題和圖像。標題和圖像分為兩個類,一類是自己的圖像和文字(格式為.png);另一類是系統提供的圖像和文字。
首先添加圖像到項目中,(在資源文件夾下)
添加UITabBarItem代碼到cityViewController.m的viewDidLoad方法下,這裡使用用戶自己的圖像,圖像名是:GoldenGateBridge.png
[plain]
- (void)viewDidLoad {
//創建一個有邊框的文體按鈕,按下後,調用視圖控制器上的discount方法
UIBarButtonItem *discountButton = [[UIBarButtonItem alloc]
initWithTitle:@"折扣信息" style:UIBarButtonItemStyleBordered
target:self action:@selector(discount:)];
self.navigationItem.leftBarButtonItem = discountButton;//設置為左邊按鈕
[discountButton release];//釋放內存
//設置視圖控制器在標簽欄上的標題和圖像
// 文字是:旅游指南。圖像是:GoldenGateBridge.png
UITabBarItem *item = [[UITabBarItem alloc]
initWithTitle:@"旅游指南"
//initWithTabBarSystemItem:UITabBarSystemItemBookmarks
image:[UIImage imageNamed:@"GoldenGateBridge.png"]
tag:0];
self.tabBarItem = item;
[item release];
[super viewDidLoad];
}
添加UITabBarItem代碼到MeiShiTianDi.m的viewDidLoad方法下,這裡使用系統提供的圖像,圖像名是:UITabBarSystemItemBookmarks,當然,本例還注釋掉了使用用戶自己的圖像的兩行代碼。如果你交換一下,也能運行。
[plain]
- (void)viewDidLoad {
//UIImage *tabImage = [UIImage imageNamed:@"shrimp.jpg"];
//設置視圖控制器在標簽欄上的標題和圖像
// 文字是:美食天地。圖像是:UITabBarSystemItemBookmarks
UITabBarItem *item = [[UITabBarItem alloc]
initWithTitle:@"美食天地"
initWithTabBarSystemItem:UITabBarSystemItemBookmarks
//image:tabImage
tag:0];
//本例還注釋掉了使用用戶自己的圖像shrimp.jpg的兩行代碼。如你交換一下也能運行
self.tabBarItem = item;
[item release];
[super viewDidLoad];
}