定制导航栏的返回按钮

导航栏自带一个返回按钮,我们需要定制它的样式,这可以有许多办法。比如 Hack 导航栏的视图层次。如果你不想 Hack 导航栏,那么你可以使用NavigationBarDelegate。问题在于,如果是导航控制器自带的NavigationBar,你将不能访问NavigationBar(程序会Crash)。这是苹果文档中的说明:

Note that if you use aUINavigationController object to manage hierarchical navigation, you should notdirectly access the navigation bar object.

这里,我们提供另一种“定制”方法。也许不能称之为定制,因为我们实际上是将默认的返回按钮隐藏了,并提供一个自定义的返回按钮作为导航栏的leftButton。使用这种方法,我们不仅可以定制按钮的样式(标题和背景图片),而且可以触发自定义的方法。默认的返回按钮动作是popViewController,我们可以修改为其他动作。

这个过程大概分为4个步骤:

1、隐藏默认返回按钮,这是通过设置navigationItem的hidesBackButton为YES做到的:

// 隐藏默认的"返回"按钮

[self.navigationItemsetHidesBackButton:YES];

 

2、自定义一个BarButtonItem。首先,我们定制一个UIButton。 这个UIButton用buttonWithType:UIButtonTypeCustom方法初始化。然后用setBarckgroundImage方法定制按钮的背景图片,用addTarget方法指定按钮的事件处理方法。这样我们就获得了一个完全定制的Button。BarButtonItem有一个initWithCustomView:的初始化方法。我们可以把一个定制的视图(比如我们定制的Button)作为这个方法的参数,构建出一个BarButtonItem。

 

// 自定义导航栏的"返回"按钮

    UIButton *btn = [UIButtonbuttonWithType:UIButtonTypeCustom];

btn.frame = CGRectMake(15, 5, 38, 38);

[btn setBackgroundImage:[UIImageimageNamed:@"按钮-返回1.png"] forState:UIControlStateNormal];

[btn addTargetselfaction@selector(goBackAction) forControlEventsUIControlEventTouchUpInside];

    UIBarButtonItem*back=[[UIBarButtonItemalloc]initWithCustomView:btn];

 

3、把BarButtonItem 设置为 navigationItem的leftBarButton。

 

// 设置导航栏的leftButton

self.navigationItem.leftBarButtonItem=back;

   

4、编写Button的事件代码。

-(void)goBackAction{

// 在这里增加返回按钮的自定义动作

[self.navigationControllerpopViewControllerAnimated:YES];

}

用UINavigationController实现在两个页之间导航(下)——书第七章 P143

 

(续前)

 

第七步:UINavigationItemUIBarButtonItem

通常每个(指任何)视图控制器都可以定义一个UINavigationItemUINavigationItem类就是实现这些功能的,这个类包含了如下表:

左边按钮

标题视图

右边按钮

leftBarButtonItem

titleView

rightBarButtonItem

当它所属的视图控制器在导航控制器所控制的堆栈顶部时,即调用(也就是说该视图控制器即将要显示时),系统自动显示该视图控制器的UINavigationItem,开发人员无需编写任何代码来调用UINavigationItem,但之前必须要设置好。上面程序代码中已经有定制好的导航栏左右按钮,简述说明如下:

定制返回按钮:在缺省情况下,下一页上的返回按钮上的文字是上一页的标题,可以在程序中修改为其它文字,要记住!返回按钮是放在上一页的视图控制器上的,所以必须在上一页对应的视图控制器的实现文件(*.m)中去修改。如在上面lvyouAppDelegate.m中有如下代码:(图中绿色代码部分)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {   

   ……

    navController = [[UINavigationController alloc] init];//初始化导航控制器

    //定义名称为“所有城市”的返回按钮。该按钮无需targetaction

//因为系统已经实现了返回功能。Style是显示风格

    UIBarButtonItem *backButton =

       [[UIBarButtonItem allocinitWithTitle:@"所有城市"

           style:UIBarButtonItemStyleBordered

           target:nil action:nil];

    //设置启动应用时第一个要显示的视图控制器,这里是cityViewContrl

    cityViewController *cityViewContrl = [[cityViewController alloc] init];

    cityViewContrl.title = @"旅游指南";//设置第一个视图控制器的标题

    //设置返回按钮

    cityViewContrl.navigationItem.backBarButtonItembackButton;

    [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中去修改,在它原代码中有如下代码:(图中绿色代码部分)

- (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中去修改,在它原代码中有如下代码:(图中绿色代码部分)

- (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的标签栏最多可显示五个标签

定制导航栏的返回按钮_第1张图片

当你选择某一个视图控制器时,该视图控制器就执行。当你选择另一个视图控制器时,当前视图控制器的状态被保留。非常类似微软中的多窗口的概念。

关系:               平等关系             上、下级之间关系

标签栏控制器

UITabBarController

导航控制器

(旅游信息)

一般视图控制器

cityViewController

一般视图控制器

CityDetailViewController

一般视图控制器

(美食天地)

MeiShiTianDi

 

下面我们将创建一个标签栏控制器,如上表,它有两个标签“旅游信息”和“美食天地”。“旅游信息”由于前面已经完成,它管理着两个视图控制器(cityViewController、 CityDetailViewController),因此,下面重点讲解未完成的工件。

1、项目的委托AppDelegate声明注册一个标签控制器、初始化后放到主窗口Window

首先:因为项目名称仍然是lvyou,所以要在项目.h中(lvyouAppDelegate.h)声明一个标签控制器:

//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:navControllerviewController,nil];

    [viewController release];//因它不是第一个视图控制器,故释放内存

    //定义名称为“所有城市”的返回按钮。该按钮无需targetaction

//因为系统已经实现了返回功能。Style是显示风格

    UIBarButtonItem *backButton =

        [[UIBarButtonItem allocinitWithTitle:@"所有城市"

            style:UIBarButtonItemStyleBordered

            target:nil action:nil];

    //设置启动应用时第一个要显示的视图控制器,这里是cityViewContrl

    cityViewController *cityViewContrl = [[cityViewController alloc] init];

    cityViewContrl.title = @"旅游指南";//设置第一个视图控制器的标题

    //设置返回按钮

    cityViewContrl.navigationItem.backBarButtonItembackButton;

    [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(美食天地)放在标签控制器上。——(上一步已经完成!)

//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.mviewDidLoad方法下,这里使用用户自己的图像,图像名是:GoldenGateBridge.png

 - (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.mviewDidLoad方法下,这里使用系统提供的图像,图像名是:UITabBarSystemItemBookmarks,当然,本例还注释掉了使用用户自己的图像的两行代码。如果你交换一下,也能运行。

- (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];

}



你可能感兴趣的:(定制导航栏的返回按钮)