在使用导航控制器进行控制器的返回操作时,是通过pop()方法将当前的控制器移出栈顶控制器,并将上一个进栈的控制器移入栈顶控制器并显示其视图。在大多数应用中,通常将这种返回操作设置给导航控制器导航栏中的backBarButtonItem控件来完成,例如iphone中的设置界面(如下图所示),当完成"General"的设置后,点击"setting"即可跳转到上一级控制器。但是在UINavigationItem下还有一个leftBarButtonItem,同样可以设置控制器的返回,下面就将这两个控件的使用进行简单的说明。
在对控制器的返回按钮(UIBarBUttonItemm是一种特殊的Button)进行设置前,需要弄清楚UINavigationItem和UINavigationBar的区别。UINavigationBar的功能类似于UINavigationController中的栈,UINavigationController管理的是控制器的栈,而UINavigationBar管理的是UIBarButtonItem。在UINavigationController中有一个UINavigationBar类的属性-navigationBar,查看这个属性(@property(nonatomic,readonly) UINavigationBar *navigationBar; // The navigation bar managed by the controller. Pushing, popping or setting navigation items on a managed navigation bar is not supported.),虽然在UINavigationBar中有push、pop NavigaitonItem的方法,但我们看到在属性后又这样注释:“这个navigationbar是通过控制器来管理的,它本身不支持pushing,poping或者setting 一个navigationbar”,说明UInavigationItem的pop、push方法是由系统自动管理的,我们仅需知道UINavigationController push或者pop一个控制器的同时,UInavigationBar也在对应的push和pop UINavigationItem,导航栏和控制器是一一对应的同步关系。
那么了解了UINavigationBar的作用后,我们来了解一下UINavigationItem。UINavgationItem管理着显示在UINavigationBar上的按钮和图片,每一个push进栈的控制器都会自带一个navigationbar,navigationbar要实现显示图片和button,就需要通过UINavtionItem完成。为了验证以上说法,我们也可以查看UINavigationItem的类属性,UINavigationItem包含了NavigaitonBar视图的全部元素(如title,tileview,backBarButtonItem等,同时又受当前栈顶控制器管理,即NavigaitonBar形成整个NavigationController的导航视图,然后每个NavigationController页面的导航栏元素由所在页面的UINavigationItem管理。简单的概括:控制器视图中的导航栏显示由UINavigationBar和UiNavigationItem共同完成,在控制器进行跳转时,UINavigationBar管理导航栏与栈顶控制器的对应关系,而UINavigationItem管理导航栏的显示内容。
现在我们就可以通过两种不同的方式来设置导航控制器上的返回按钮:
首先我们定义两个控制器对象:
UIViewController *AController =[[UIViewController alloc]init];
UIViewController *Bcontroller = [[UIViewController alloc]init];
在Appdelegate中将AController设置为主控制器,在A控制器中添加一个Button,点击后按钮后push到B控制器,设置完成后界面如下:
当不设置返回按钮的标题时,返回按钮默认显示的是上一个控制器的标题。
现在通过第一种方式更改返回按钮的显示,即通过设置backBarButtonItem来实现,但是要跳转到B控制器,需要在A控制器中进行设置,以下为在A控制器中的代码。
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor redColor]; self.navigationItem.title = @"主控制器"; //创建一个button并设置属性 UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 80, 80)]; btn.center = self.view.center; [btn setTitle:@"跳转Next" forState:UIControlStateNormal]; [btn setBackgroundColor:[UIColor blueColor]]; [self.view addSubview:btn]; //添加点击事件 [btn addTarget:self action:@selector(BtnClick) forControlEvents:UIControlEventTouchUpInside]; UIBarButtonItem *backItem = [[UIBarButtonItem alloc]initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:self action:nil]; self.navigationItem.backBarButtonItem = backItem; } -(void)BtnClick{ //创建B控制器 BViewController *Bcontroller = [[BViewController alloc]init]; //设置跳转 [self.navigationController pushViewController:Bcontroller animated:YES]; }
设置完成后改变了返回按钮的标题:
通过第二种方式修改返回按钮,则直接在当前控制器(即B控制器)中进行设置,代码如下:
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor greenColor]; self.navigationItem.title = @"NO.2控制器"; //创建leftItem UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemReply target:self action:@selector(btnClick)]; //设置给leftBarButtonItem self.navigationItem.leftBarButtonItem = leftItem; } -(void)btnClick{ [self.navigationController popToRootViewControllerAnimated:YES]; }
设置后更改了返回按钮的样式,效果如下:
两种方式都可以实现控制器的正常跳转,只要理解了UINavigationBar和UINavigationItem的不同作用,在开发中实现相关控制器导航栏的设置将会变得很简单。如描述有误请见谅,期待与您一起交流!