UI:UINavigationController、界面通信
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、界面通信的更多相关文章
- Mac OS X 10.9.3 UI 设置界面无法设置时区解决
10.9.3 在选项设置里无法设置时区,表现为选择时区的点的位置后无法保存,导致系统时间错乱,解决方法是用终端设置: sudo systemsetup -gettimezone sudo system ...
- ##DAY8 界面通信
##DAY8 界面通信 注意:延展中写的东西只能在类内使用 #pragma mark ———————属性传值—————————— (第一个页面往第二个页面传值) 一.属性传值:(第一个页面往第二个页面 ...
- 精美对UI设计界面赏析
最美的UI设计界面赏析 . 喜欢就关注我吧
- UI基础:UINavigationController、界面通信
UINavigationControlle UINavigationController:导航控制器,是iOS中最常用的多视图控制器之一,它用来管理多个视图控制器.也称为多视图控制器. 导航控制器可以 ...
- Android线程---UI线程和非UI线程之间通信
近期自学到了线程这一块,用了一上午的时间终于搞出来了主.子线程间的相互通信.当主线程sendMessage后,子线程便会调用handleMessage来获取你所发送的Message.我的主线程 ...
- pyqt5 在qt designer后以弹窗的方式连接多个UI图形界面
当我们通过pyqt开发时,eric6为我们提供了一个方便的工具:图形化的绘制UI工具--qt designer. 我们可以通过它开发多个UI,然后利用信号-槽工具,将功能代码附着在上面.也可以将多个界 ...
- pyqt5通过qt designer 设计方式连接多个UI图形界面
当我们通过pyqt开发时,eric6为我们提供了一个方便的工具:图形化的绘制UI工具--qtdesigner.我们可以通过它开发多个UI,然后利用信号-槽工具,将功能代码附着在上面.也可以将多个界面连 ...
- OpenLayers学习笔记3——使用jQuery UI美化界面设计
PC端软件在开发是有较多的界面库能够选择,比方DevExpress.BCG.DotNetBar等,能够非常方便快捷的开发出一些炫酷的界面,近期在学习OpenLayers.涉及到web前端开发,在设计界 ...
- 在已有QT项目中添加多个UI布局界面
1.在工程中右键->添加新文件,按图选择 2.选择窗口部件 3.创建UI控制类 注意上图红框中命名按实际需要定义,否则后期改动要修改UI文件参数 4.修改UI文件,框1是窗口部件父类,框2是UI ...
随机推荐
- 【英语】Bingo口语笔记(23) - 万圣节系列
jack-o-lantern 杰克灯(南瓜灯) spooky 幽灵般的
- 摘录:官方文档对ROWID虚拟行的定义
ROWID Pseudocolumn For each row in the database, the ROWID pseudocolumn returns the address of the r ...
- 【转】uboot移植(一)BootLoader基本概念
原文网址:http://blog.chinaunix.net/uid-25445243-id-3869348.html 一.BootLoader简介1.1.嵌入式Linux软件结构与分布 在一般情况下 ...
- 【转】linux设备驱动程序中的阻塞机制
原文网址:http://www.cnblogs.com/geneil/archive/2011/12/04/2275272.html 阻塞与非阻塞是设备访问的两种方式.在写阻塞与非阻塞的驱动程序时,经 ...
- 15stl模板
1.stack #include<iostream> #include<stdio.h> #include<stack> using namespace std; ...
- nmon基础
nmon是分析 AIX 和 Linux 性能的免费工具 最简单的安装方式(Ubuntu apt源) sudo apt-get install nmon 在terminal下打开nmon 敲CMD,出现 ...
- javascript --- 面向对象 --- 封装
javascript中有原型对象和实例对象 如有疑问请参考:http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_enca ...
- 标准IO
标准IO由ISO C 标准的IO库,它处理了很多底层细节,比如合适的缓冲大小等等,因此更易于使用,但是也引入了一些其他问题. 流向 标准IO使用FILE对象关联流,流可以是面向宽字节的也可以是面向单字 ...
- bzoj 3809 Gty的二逼妹子序列(莫队算法,块状链表)
[题意] 回答若干个询问,(l,r,a,b):区间[l,r]内权值在[a,b]的数有多少[种]. [思路] 考虑使用块状链表实现莫队算法中的插入与删除. 因为权值处于1..n之间,所以我们可以建一个基 ...
- 一行 Python 实现并行化 -- 日常多线程操作的新思路
春节坐在回家的火车上百无聊赖,偶然看到 Parallelism in one line 这篇在 Hacker News 和 reddit 上都评论过百的文章,顺手译出,enjoy:-) http:// ...