IOS中实现对控制器的管理的控制器有:UINavigationController 和 UITableBarController 两个控制器。下面是主要学习前者。

参考

⼀、UINavigationController

⼆、定制UINavigationBar

三、界⾯间通信

一、UINavigationController

UINavigationController:导航控制器,是iOS中最常⽤的多视图控制器之⼀,它⽤来管理多个视图控制器。 导航控制器可以认为是管理控制器的控制器,主要管理有层级关系的控制器。

UINavigationController继承于UIViewController,以栈的⽅式管理所控制的视图控制器,⾄少要有⼀个被管理的视图控制器,这个控制器我们称作导航控制器的根视图控制器。 任何继承⾃UIViewController的类都可以作为根控制器。

工作方式

UINavigationController 通过栈的⽅式管理控制器的切换,控制⼊栈和出栈来展⽰各个视图控制器。

UINavigationController 的 ContentView ⾥始终显⽰栈顶控制器的view。
viewControllers 属性存储了栈中的所有被管理的控制器
navigationController 属性,⽗类中的属性,每个在栈中的控制器,都能通过此属性,获取⾃⼰所在的 UINavigationController 对象。

⼊栈和出栈

pushViewController:animated //进⼊下⼀个视图控制器
popViewControllerAnimated: //返回上⼀个视图控制器
popToViewController:animated //返回到指定的视图控制器
popToRootViewControllerAnimated //返回到根视图控制器

常⽤属性

viewControllers //所有处于栈中的控制器
topViewController //位于栈顶的控制器
visibleViewController //当前正在显⽰的控制器
navigationBar //导航条

⼆、定制UINavigationBar

UINavigationBar

navigationBar—导航条,iOS7之后默认是透明的,iOS7之前默认是不透明的。

navigationBar 在透明情况下,与 contentView 会重合⼀部分区域。
navigationBar 在不透明情况,contentView 跟在 navigationBar 的下⾯。
navigationBar 竖屏下默认⾼度44,横屏下默认⾼度32

⾃定义navigationBar

barTintColor //设置导航条的颜⾊
setBackgroundImage:forBarMetrics: //导航条加背景图⽚

管理UINavigationItem

UINavigationBar 除了能定义⾃⾝的样式外,还管理⼀组 UINavigationItem。与 UINavigationController 相似,UINavigationBar 也是以栈的⽅式管理⼀组 UINavigationItem。提供 push 和 pop 操作 item。

每个视图控制器都有⼀个navigationItem属性。navigationItem中设置的左按钮、右按钮、标题等,会随着控制器的显⽰,也显⽰到 navigationBar上
UINavigationItem

UINavigationItem属于MVC中的M。封装了要显⽰在UINavigationBar上的数据。
title //标题
titleView //标题视图 (可是Button、 UIView )
leftBarButtonItem //左按钮
rightBarButtonItem //右按钮

leftBarButtonItems //多个左按钮(这里是个数组)
rightBarButtonItems //多个右按钮

UIBarButtonItem

UIBarButtonItem属于MVC的M。定义了UINavigationItem上按钮的触
发事件,外观等
-initWithBarButtonSystemItem:target:action:
-initWithTitle:style:target:action:
-initWithImage:style:target:action:
tintColor

三、⻚⾯间通信

属性传值

第⼀个视图控制器如何获得第⼆个视图控制器的部分信息?例如:第⼀个界⾯中lable显⽰第⼆个界⾯textField中的⽂本

⻚⾯间通信

代理传值

UINavigationController 以栈的⽅式管理视图控制器。通过push和pop 控制跳转

UINavigationBar管理⼀组UINavigationItem,UINavigationItem包含了 UIBarButtonItem。
使⽤属性传值解决从前往后传值的问题
使⽤delegate解决从后往前传值的问题

代码

#import "AppDelegate.h"
#import "RootViewController.h" @interface AppDelegate () @end @implementation AppDelegate -(void)dealloc{
[_window release];
[super dealloc];
} - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible]; RootViewController * RootVC = [[RootViewController alloc]init];
//创建一个导航控制器 (并且制定 RootVC 为导航控制器的根视图控制器)
UINavigationController * navl = [[UINavigationController alloc]initWithRootViewController:RootVC];
//指定导航控制器为窗口根视图控制器 (window -> navl -> RootVC)
self.window.rootViewController = navl;
[RootVC release]; return YES;
}
AppDelegate.m
//
// RootViewController.m #import "RootViewController.h"
#import "SecondViewController.h" @interface RootViewController () @end @implementation RootViewController - (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor orangeColor];
//设置导航栏的属性
[self commonSettings];
}
/*
self.navigationController 取到来管理我们当前视图控制器的导航控制器
*/
-(void)commonSettings{
//1.改变导航栏的颜色 (IOS 7之后新出的属性)(导航栏 是44像素 状态条20像素)
// self.navigationController.navigationBar.barTintColor = [UIColor cyanColor];
self.navigationController.navigationBar.barTintColor = [UIColor grayColor];
//2.导航条的半透明效果 (默认的是打开的)
//关闭半透明的效果
self.navigationController.navigationBar.translucent = NO;//半透明效果也叫 毛玻璃效果 (**)
//3.导航条是否隐藏
self.navigationController.navigationBarHidden = YES;
self.navigationController.navigationBarHidden = NO;
self.navigationController.navigationBar.hidden = YES;
self.navigationController.navigationBar.hidden = NO;
//4.导航条的标题内容的颜色
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];//如果为导航条控件添加按钮(按钮上的图片会被渲染)我们要对图片进行渲染 例如Button上添加的图片后,吧图片的渲染改为原图模式 [[UIImage imageNamed:@"NavBtnBack"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
//当导航条上的控件为图片的时候,我们需要对图片进行一个渲染设置,默认的系统的渲染是渲染模板,如果需要设置为原图,则需要设置为原图渲染
//设置当前界面的导航栏的属性<当前界面的哦>
[self customesizeNavigationconBar];
self.navigationController.title = @"行健 -—— 主页面";
//5.设置导航条的标题字体大小和颜色
NSDictionary * dic = @{NSFontAttributeName:[UIFont systemFontOfSize:],NSForegroundColorAttributeName:[UIColor orangeColor]};
self.navigationController.navigationBar.titleTextAttributes = dic;
//6.设置背景图片
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"NavBar_64"] forBarMetrics:UIBarMetricsDefault];
/*不同尺寸的图片,导航条的显示效果不一样
小于 44 像素 将图片拉伸,同时铺满状态条和导航条的空间
等于 44 像素 只会显示在导航条
大于 44 像素小于 64像素 将图片平铺在状态条和导航条的空间
等于 64 像素 图片正好显示在导航条以及状态条上
*/ //上面的属性设置都是一个导航控制器的公共的属性(*******)
//布局一个 Button
UIButton * button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(, , , );
button.backgroundColor = [UIColor grayColor];
[button setTitle:@"进入下一界面" forState:UIControlStateNormal];
//添加点击事件
[button addTarget:self action:@selector(pushToNext:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
UISegmentedControl * segment = [[UISegmentedControl alloc]initWithItems:@[@"好友",@"电话",@"QQ"]];
self.navigationItem.titleView = segment;
//IOS6.0 和 IOS7.0 导航栏的布局都是 // // UIView * uiView = [[UIView alloc]initWithFrame:CGRectMake(20, 20, 20, 20)];
// uiView.backgroundColor = [UIColor redColor];
// self.navigationItem.titleView = uiView;
// [uiView release]; // segment.frame = [[UIScreen mainScreen]bounds];
//设置左边内容
UIBarButtonItem * left = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(handleLeftAction:)];
self.navigationItem.leftBarButtonItem = left;
[left release];
//设置右边内容
// UIBarButtonItem * right = [[UIBarButtonItem alloc]initWithTitle:@"右边内容" style:UIBarButtonItemStylePlain target:self action:@selector(handleRightAction:)];
UIBarButtonItem * right = [[UIBarButtonItem alloc]initWithImage:[[UIImage imageNamed:@"NavBtnBack"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:segment action:@selector(handleRightAction:)];
// UIBarButtonItem * right = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(handleRightAction:)];
self.navigationItem.rightBarButtonItem = right;
[right release]; }
#pragma mark-------------pushToNext-- 进入下一页面---------------
-(void)pushToNext:(UIButton * )sender{
//创建第二个视图控制器
SecondViewController * SecondVC = [[SecondViewController alloc]init];
//利用当前控制器的导航控制器 去进入到下一个页面(最好改变一下要跳闸到的页面的背景颜色,不染有卡顿效果)
[self.navigationController pushViewController:SecondVC animated:YES];
self.navigationItem.title = @"行健的第二页面";
//释放所有权
[SecondVC release]; }
#pragma mark-------------设置当前界面的导航栏的属性<当前界面的哦>---------------
-(void)customesizeNavigationconBar{
//设置导航条的标题
self.navigationItem.title = @"行健主页面<第一页面>";
//设置导航条的标题视图
// self.navigationItem.titleView =
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
if ([self isViewLoaded]&& self.view.window == nil) {
self.view = nil;
}
}
#pragma mark-------------设置左边& 右边 按钮内容 lefttBarButton 事件---------------
-(void)handleLeftAction:(UIBarButtonItem * )leftBarButton{
NSLog(@"测试");
}
-(void)handleRightAction:(UIBarButtonItem *)rightButton{
NSLog(@"测试右边按钮");
} @end
RootViewController.m
#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor greenColor];
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} @end
SecondViewController.m

 

视图的生命周期

指定的初始化方法       initWithNibName....

创建视图加载视图       loadView

视图已经加载           viewDidLoad

视图将要出现           viewWillAppear

视图确实出现           viewDidAppear

视图将要消失           viewWillDisappear

视图确实消失           viewDidDisappear

second <--> third  (两个界面跳转时) 视图的出现/消失的过程

second --> third (从前到后)

前 viewWillDisappear --> 后 viewWillAppear --> 前 viewDidDisappear --> 后 viewDidAppear

second <-- third (从后到前)

后 viewWillDisappear --> 前 viewWillAppear --> 后 viewDidDisappear --> 前 viewDidAppear

页面传值

1.创建一个根视图控制器,设为服从导航控制器管理(指定导航控制器为window的根控制器)

RootViewController * RootVC = [[RootViewController alloc]init];

UINavigationController * navl = [[UINavigationController alloc]initWithRootViewController:RootVC];

self.window.rootViewController = navl;

[RootVC release];

[navl release];

总结: 在传值的时候,对于属性为 数组的 一定要记得初始化

代码

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

-(void)dealloc;
@end
AppDelete.h文件
#import "AppDelegate.h"
#import "RootViewController.h"
#import "FRootViewController.h" @interface AppDelegate () @end @implementation AppDelegate
-(void)dealloc{
[_window release];
[super dealloc];
}
//界面跳转的时刻同时传值
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible]; RootViewController * RootVC = [[RootViewController alloc]init];
UINavigationController * navl = [[UINavigationController alloc]initWithRootViewController:RootVC];
self.window.rootViewController = navl;
[RootVC release];
[navl release]; // FRootViewController * frVC = [[FRootViewController alloc]init];
// UINavigationController * navl = [[UINavigationController alloc]initWithRootViewController:frVC];
// self.window.rootViewController = navl;
// [frVC release];
// [navl release]; return YES;
}
AppDelete.m文件
#import <UIKit/UIKit.h>

@interface RootViewController : UIViewController
@property(nonatomic,retain)UITextField * tf;
@property(nonatomic,retain)UILabel * lable;
@end
#import "RootViewController.h"
#import "FirstViewController.h" #pragma Mark 代理传值 4 前一个界面服从协议
@interface RootViewController ()<UITextFieldDelegate,PassValueDelegate> @end /*界面之间的传值
1.从前往后传值——利用属性传值
2.从后往前传值——代理传值
——Block传值
《代理的步骤》
A.在后一个界面制定协议
B.在后一个界面设置代理属性
C.在前一个界面进入后一个界面之前设置代理对象
D.前一个界面的类服从协议
E.前一个界面实现协议方法
F.在后一个界面消失时机,把对应的数据作为协议的方法的参数传入 3.间隔几个页面的的传值(多页面之间的传值)——单例传值
*/
@implementation RootViewController - (void)viewDidLoad {
[super viewDidLoad];
self.tf = [[UITextField alloc]initWithFrame:CGRectMake(, , , )];
_tf.layer.cornerRadius = ;
_tf.layer.borderWidth = ;
_tf.layer.borderColor = [UIColor blackColor].CGColor;
_tf.delegate = self;
_tf.placeholder = @"输入框";
[self.view addSubview:_tf];
[self.tf release]; self.lable = [[UILabel alloc]initWithFrame:CGRectMake(, , , )];
_lable.text = @"";
_lable.backgroundColor = [UIColor orangeColor];
[self.view addSubview:_lable];
[_lable release]; self.navigationController.title = @"0页面";
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"NavBar_64"] forBarMetrics:UIBarMetricsDefault]; self.view.backgroundColor = [UIColor whiteColor];
UIButton * secondButton = [UIButton buttonWithType:UIButtonTypeSystem];
secondButton.backgroundColor = [UIColor grayColor];
[secondButton addTarget:self action:@selector(pushToNext1:) forControlEvents:UIControlEventTouchUpInside];
[secondButton setTitle:@"进入下一页面" forState:UIControlStateNormal];
secondButton.frame = CGRectMake(, , , );
[self.view addSubview:secondButton]; } -(void)pushToNext1:(UIButton *)sender{
FirstViewController * firstVC = [[FirstViewController alloc]init];
#pragma Mark 代理传值 3 进入到后一个界面之前 指定代理对象
firstVC.delegate = self;
firstVC.text = self.tf.text;//传值
[self.navigationController pushViewController:firstVC animated:YES];
[firstVC release];
}
#pragma Mark 代理传值 5 前一个页面执行协议的方法
-(void)passValue:(NSString *)text{
self.lable.text = text;
}
//回收键盘
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.tf resignFirstResponder];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
if ([self isViewLoaded] && !self.view.window) {
self.view = nil;
}
} @end
RootViewController.m文件
#import <UIKit/UIKit.h>

#pragma Mark 代理传值 1 制定协议
@protocol PassValueDelegate <NSObject>
@optional
-(void)passValue:(NSString *)text;
@end @interface FirstViewController : UIViewController
//在后一个界面添加属性
@property(nonatomic,retain)NSString * text;
@property(nonatomic,retain)UITextField * tf;
#pragma Mark 代理传值 2 添加属性用来存储代理对象
@property(nonatomic,retain)id<PassValueDelegate>delegate;
@end
FirstViewController.h文件
#import "FirstViewController.h"
#import "SecondViewController.h" @interface FirstViewController () @end @implementation FirstViewController - (void)viewDidLoad {
[super viewDidLoad];
[self layoutSubViews];
} //布局
-(void)layoutSubViews{
self.tf = [[UITextField alloc]initWithFrame:CGRectMake(, , , )];
_tf.layer.cornerRadius = ;
_tf.layer.borderWidth = ;
_tf.layer.borderColor = [UIColor blackColor].CGColor;
_tf.placeholder = @"输入框";
[self.view addSubview:_tf];
[self.tf release]; UILabel * lable = [[UILabel alloc]initWithFrame:CGRectMake(, , , )];
lable.text = self.text;
lable.backgroundColor = [UIColor orangeColor];
[self.view addSubview:lable];
[lable release]; self.navigationController.title = @"1页面";
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"NavBar_64"] forBarMetrics:UIBarMetricsDefault]; self.view.backgroundColor = [UIColor lightGrayColor];
UIButton * secondButton = [UIButton buttonWithType:UIButtonTypeSystem];
secondButton.backgroundColor = [UIColor grayColor];
[secondButton addTarget:self action:@selector(pushToNext1:) forControlEvents:UIControlEventTouchUpInside];
[secondButton setTitle:@"进入下一页面" forState:UIControlStateNormal];
secondButton.frame = CGRectMake(, , , );
[self.view addSubview:secondButton];
} -(void)pushToNext1:(UIButton *)sender{
SecondViewController * secondVC = [[SecondViewController alloc]init];
[self.navigationController pushViewController:secondVC animated:YES];
[secondVC release];
}
//后一个页面将要消失的时机去传值
#pragma Mark 代理传值 6 后一个页面将要消失的时机去把本页面输入框的内容传值到前一个界面 对应的数据作为协议的参数
-(void)viewWillDisappear:(BOOL)animated{
//如果代理存在 并且 代理响应了方法
if (_delegate && [_delegate respondsToSelector:@selector(passValue:)]) {
[self.delegate passValue:self.tf.text];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
FirstViewController.m文件
#import <UIKit/UIKit.h>

@interface SecondViewController : UIViewController

@end
#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
SecondViewController.m文件

参考

UI:UINavigationController、界面通信的更多相关文章

  1. Mac OS X 10.9.3 UI 设置界面无法设置时区解决

    10.9.3 在选项设置里无法设置时区,表现为选择时区的点的位置后无法保存,导致系统时间错乱,解决方法是用终端设置: sudo systemsetup -gettimezone sudo system ...

  2. ##DAY8 界面通信

    ##DAY8 界面通信 注意:延展中写的东西只能在类内使用 #pragma mark ———————属性传值—————————— (第一个页面往第二个页面传值) 一.属性传值:(第一个页面往第二个页面 ...

  3. 精美对UI设计界面赏析

    最美的UI设计界面赏析 . 喜欢就关注我吧

  4. UI基础:UINavigationController、界面通信

    UINavigationControlle UINavigationController:导航控制器,是iOS中最常用的多视图控制器之一,它用来管理多个视图控制器.也称为多视图控制器. 导航控制器可以 ...

  5. Android线程---UI线程和非UI线程之间通信

        近期自学到了线程这一块,用了一上午的时间终于搞出来了主.子线程间的相互通信.当主线程sendMessage后,子线程便会调用handleMessage来获取你所发送的Message.我的主线程 ...

  6. pyqt5 在qt designer后以弹窗的方式连接多个UI图形界面

    当我们通过pyqt开发时,eric6为我们提供了一个方便的工具:图形化的绘制UI工具--qt designer. 我们可以通过它开发多个UI,然后利用信号-槽工具,将功能代码附着在上面.也可以将多个界 ...

  7. pyqt5通过qt designer 设计方式连接多个UI图形界面

    当我们通过pyqt开发时,eric6为我们提供了一个方便的工具:图形化的绘制UI工具--qtdesigner.我们可以通过它开发多个UI,然后利用信号-槽工具,将功能代码附着在上面.也可以将多个界面连 ...

  8. OpenLayers学习笔记3——使用jQuery UI美化界面设计

    PC端软件在开发是有较多的界面库能够选择,比方DevExpress.BCG.DotNetBar等,能够非常方便快捷的开发出一些炫酷的界面,近期在学习OpenLayers.涉及到web前端开发,在设计界 ...

  9. 在已有QT项目中添加多个UI布局界面

    1.在工程中右键->添加新文件,按图选择 2.选择窗口部件 3.创建UI控制类 注意上图红框中命名按实际需要定义,否则后期改动要修改UI文件参数 4.修改UI文件,框1是窗口部件父类,框2是UI ...

随机推荐

  1. [转]深入理解Flash Player重绘

    这个是tencent flash team的一篇文章,但团队的博客已经关闭了,所以就在这里备份下吧~ 后来有人把这篇文章又发布到9ria上了,引发了一些讨论,其中有两位大神发言了,内容在原文下方. 9 ...

  2. ECSide标签属性说明之<ec:column>

    <ec:column>标签 ◆ 属性: columnId描述: 单元格的id,相当于<td>的id属性 ◆ 属性: title描述: 列在列表表头里显示的名称. ◆ 属性: p ...

  3. hql查询语句 内存中的情况,fetch迫切查询关键字

    Classes.java package cn.itcast.hiberate.sh.domain; import java.io.Serializable; import java.util.Set ...

  4. CURL --- 命令行浏览器CURL

    CURL --- 命令行浏览器CURL   CURL --- 命令行浏览器   CURL? 嗯,说来话长了~~~~ 这东西现在已经是苹果机上内置的命令行工具之一了,可见其魅力之一斑 1)二话不说,先从 ...

  5. android启动页优化实践

    最近观看友盟统计发现App启动页跳出率很高,观看启动页的平均启动时间为2.8s,如下图: 所以一个很现实的问题就出来了,优化启动页面... (一)做了什么? 我们的启动页面主要用于展示启动页面,加载网 ...

  6. JDBC项目实践

    这几天学习了JDBC的接口,从简单的连接,到不断地对JDBC的代码进行优化,最后到实体类,DAO类的设计,现在对这几天所学做一个总结: 首先是软件的系统组成: 数据库中有很多的表:Customer,D ...

  7. 将Tomcat注册为Windows服务

    1.从官网http://tomcat.apache.org/下载Tomcat. 2.将Tomcat压缩文件解压到相应的路径下(例如E:\TomcatServer) 3.从bin目录下找到service ...

  8. 【LeetCode】9 & 234 & 206 - Palindrome Number & Palindrome Linked List & Reverse Linked List

    9 - Palindrome Number Determine whether an integer is a palindrome. Do this without extra space. Som ...

  9. JavaScript中,{}+{}等于多少?

    最近,Gary Bernhardt 在一个简短的演讲视频“Wat”中指出了一个有趣的 JavaScript 怪癖: 在把对象和数组混合相加时,会得到一些意想不到的结果. 本篇文章会依次讲解这些计算结果 ...

  10. ASP.NET 应用程序生命周期概述[转自MSDN]

    本文转自:http://msdn.microsoft.com/zh-cn/library/ms178473(VS.80).aspx 下表描述了 ASP.NET 应用程序生命周期的各个阶段.   阶段 ...