IOS 学习笔记(2) 视图UINavigationController
1.栈
导航控制器自身有一个针对显示内容的栈,也有一个对于导航栏的栈,当有新的内容欲显示时,进的导航栏和显示内容会被压入此栈,这样原本显示中的导航栏和显示内容则会进入到栈的更深一层中,根据栈的先进后出功能,最后被压入栈的界面先出栈。不过导航视图控制器始终有两个栈,一个栈控制导航栏内容,一个栈控制显示内容,并且开发者有义务也必须保持这两个栈的深度一致,否则程序会将不同步异常抛出。
对于显示内容的压栈操作API如下:
-(void)pushViewController:(UIViewController *)viewController animated:(BOOL )animated
对于显示内容的出栈操作API如下:
-(UIViewController *)popViewControllerAnimated:(BOOL)animated
-(NSArray *)popToRootViewControllerAnimated:(BOOL)animated
-(NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated
在pushViewController视图控制器对象时,UINavigationController会对此对象retain一次,待到pop时才release,也就是说在pop时试图控制器的引用计数应该为0.
不过有些时候,特别是当开发者重写导航栏或者重写导航试图控制器时,还是会需要手动保持层次的平衡,这是可以额外的调用UINavigationBar对象的一下几个API
-(void)pushNavigationItem:(UINavigationItem *)item animated:(BOOL)animated
-(UINavigationItem *)popNavigationItemAnimated:(BOOL)animated
2.导航视图控制器的一下特性事例
(1)对UIViewController对象的navigationItem.title属性进行字符串赋值
(2)对UIViewController对象的title属性进行字符串配置
所以在viewDidLoad中修改如下
self.navigationItem.title=@"";
self.title=@""
(3)导航栏左中右位置的配置
-(void)initNavBar
{
//创建一个UISegmentControl控件
UISegmentedControl *aSegment=[[UISegmentedControl alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 1000.0f, 30.0f)]; //为控件新增三段内容
[aSegment insertSegmentWithTitle:@"" atIndex: animated:NO]; [aSegment insertSegmentWithTitle:@"" atIndex: animated:NO]; [aSegment insertSegmentWithTitle:@"" atIndex: animated:NO]; //第一次出来显示的选择
aSegment.selectedSegmentIndex=; //将segment设置在中间
self.navigationItem.titleView=aSegment; //为导航栏左边配置一个系统自带样式的按钮
//按钮相应函数时actionDone:
self.navigationItem.leftBarButtonItem=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(actDone:)]; //为导航栏右边配置一个系统自带式样的按钮
//按钮相应函数是actNext:
self.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(actNext:)];
}
接下来就是工具栏的配置了。和导航栏一样,导航视图控制器也只有唯一一个底部的工具栏,如果我们打算使用导航控制器的那个工具栏,也需要遵循他的模式来进行。
如果我们并非打算所有视图都需要显示这个工具栏,所以我们将工具栏的配置代码放置在viewWillAppear函数中,每当视图显示时,进行工具栏的更新
-(void)updateToolBar
{
//配置工具栏的样式
self.navigationController.toolbar.barStyle=UIBarStyleDefault; //显示工具栏
[self.navigationController setToolbarHidden:NO animated:YES];
self.toolbarItems=[[NSArray alloc]initWithObjects:[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(actAdd:)], nil]; }
效果图如:
(4)导航栏右位置的多按钮
撰写initNavBar函数,以及隐藏工具栏,代码如下:
-(void)initNavBar
{
UILabel *labTitle=[[UILabel alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 1000.0f, 44.0f)];
labTitle.backgroundColor=[UIColor darkGrayColor];
labTitle.textColor=[UIColor whiteColor];
labTitle.text=@"看右侧";
labTitle.textAlignment=NSTextAlignmentCenter; //配置一个UILabel到导航栏中间
self.navigationItem.titleView=labTitle; UIView *aView=[[UIView alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 60.0f, 36.0f)];
aView.backgroundColor=[UIColor clearColor]; //第一个按钮
UIButton *buttonA = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[buttonA setTitle:@"按钮" forState:UIControlStateNormal];
buttonA.titleLabel.font=[UIFont systemFontOfSize:12.0f];
buttonA.frame=CGRectMake(0.0f, CGRectGetHeight(aView.frame)/-13.0f, 30.0f, 26.0f);
[buttonA addTarget:self action:@selector(actButtonA:) forControlEvents:UIControlEventTouchUpInside];
[aView addSubview:buttonA]; //第二个按钮
UIButton *buttonB = [UIButton buttonWithType:UIButtonTypeInfoLight];
buttonA.frame=CGRectMake(CGRectGetWidth(aView.frame)-CGRectGetWidth(buttonA.frame), CGRectGetHeight(aView.frame)/-CGRectGetHeight(buttonA.frame), CGRectGetWidth(buttonA.frame), CGRectGetHeight(buttonA.frame));
[buttonB addTarget:self action:@selector(actButtonB:) forControlEvents:UIControlEventTouchUpInside];
[aView addSubview:buttonB]; self.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc]initWithCustomView:aView]; //对于navgationItem左侧的返回按钮的修改
self.navigationItem.backBarButtonItem=[[UIBarButtonItem alloc]initWithTitle:@"Go Back" style:UIBarButtonItemStyleBordered target:self action:NULL]; }
导航栏左右两侧的控件宽度是没有固定的上限的,也就是说如果设置的过于宽,会对另一头以及中间部分的显示内容产生影响。
这里,右侧的两个按钮都暂时使用了系统自带的按钮式样。由于是UIButton,可以添加图片的
效果如下:
5.工具栏内容修改和全屏显示
首先需要对当前的工具栏内容进行修改,实现代码的原理就是对工具栏的元素数组进行再次赋值
-(void)initNav
{
self.navigationItem.title=@"更改工具栏按钮";
} -(void)updateToolBar
{
//工具栏的元素
self.toolbarItems=[[NSArray alloc]initWithObjects:[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:self action:@selector(actStop:)],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:@selector(actPlay:)],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:@selector(actCamera:)],nil
]; //修改工具栏的样式
self.navigationController.toolbar.barStyle=UIBarStyleBlackOpaque;
[self.navigationController setToolbarHidden:NO animated:YES]; }
工具栏样式设置为UIBarStyleBlackOpaque,是工具栏有某种透明的能力,连导航栏和系统的状态栏都能够透明甚至隐藏,从而实现真正的一个试图占满整个屏幕的情况。
这种全屏显示的模式常见于视频电影播放的应用程序和图片游览的应用程序,对于全屏的支持,UIViewController主要依靠wantsFullScreenLayout属性设置成YES来辅助实现。并且在UIViewController中属性Top Bar选成Translucent Black Navigation,如图
由于只在当前视图中呈现透明黑色样式的导航栏,所以在当前视图被推出栈之前,将样式变回才好,相关代码改写如下:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self updateToolBar];
[self updateNavBarStyle:YES];
} -(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self updateNavBarStyle:NO];
} -(void)updateNavBarStyle:(BOOL)bAppear
{
//全屏模式
if(bAppear)
{
self.navigationController.navigationBar.translucent=YES;
self.navigationController.navigationBar.barStyle=UIBarStyleBlackTranslucent;
}
//默认模式
else
{
self.navigationController.navigationBar.translucent=NO;
self.navigationController.navigationBar.barStyle=UIBarStyleDefault;
}
}
全屏模式一般需要一个外部触发器,不如我们自己制作一个触发器,让用户在视图上点击一次作为全屏和默认模式的切换信号。把这个手势事件在viewDidLoad中先进性注册。
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self initNav]; //单击手势的注册
UITapGestureRecognizer *tapGesture=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(actTap:)];
[self.view addGestureRecognizer:tapGesture];
}
对于手势的响应函数
-(IBAction)actTap:(id)sender
{
//全屏中
if(self.navigationController.navigationBarHidden)
{
//状态栏显示
[[UIApplication sharedApplication]setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade]; //导航栏显示
[self.navigationController setNavigationBarHidden:NO animated:YES];
//工具栏显示
[self.navigationController setToolbarHidden:NO animated:YES];
}
//非全屏中
else
{
//状态栏隐藏
[[UIApplication sharedApplication]setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade]; //导航栏隐藏
[self.navigationController setNavigationBarHidden:YES animated:YES]; //工具栏隐藏
[self.navigationController setToolbarHidden:YES animated:YES];
}
}
随后需要修改UISegmentController上第二标题“工具栏”
修改UISegment 点击事件 actNext的方法如下:
-(IBAction)actNext:(id)sender
{
switch(_mySegments.selectedSegmentIndex)
{
case :
break;
case :
break;
case :
HBNavToolBarController *aNewVC=[[HBNavToolBarController alloc]init];
aNewVC.wantsFullScreenLayout=YES;
break;
default:
break;
}
[self.navigationController pushViewController:aNewVC animated:YES];
}
显示结果如下:
6.动画过度和超大视图
- (IBAction)actNext:(id)sender {
HBResizeViewController *resizeVC=[[HBResizeViewController alloc]init]; //自定义动画
CATransition *animation=[CATransition animation];
animation.delegate=self;
animation.duration=0.5;
animation.timingFunction=UIViewAnimationCurveEaseInOut;
animation.removedOnCompletion=NO;
animation.type=@"pageCur1";
animation.subtype=kCATransitionFromBottom;
animation.endProgress=1.0f;
[self.navigationController.view.layer addAnimation:animation forKey:@"animation"];
[self.navigationController pushViewController:resizeVC animated:NO]; }
当需要执行自定义动画是,往往会将导航控制器的默认栈动画首先进行关闭,即对pushViewController: animated: 方法的第二个参数传入NO
IOS 学习笔记(2) 视图UINavigationController的更多相关文章
- iOS学习笔记——滚动视图(scrollView)
滚动视图:在根视图中添加UIScrollViewDelegate协议,声明一些对象属性 @interface BoViewController : UIViewController<UIScro ...
- [ios学习笔记之视图、绘制和手势识别]
一 视图 二 绘制 三 手势 00:31 UIGestureRecognizer 抽象类 两步 1添加识别器(控制器或者视图来完成) 2手势识别后要做的事情 UIPanGestureRecognize ...
- IOS 学习笔记(3) 视图UITabbarController
1.UITabbarViewController标签试图控制器.由于标签页本就起着分类的作用,所以往往呈现的视图内容之间,可以是毫不相关的功能. UITabbarViewController仍然继承自 ...
- iOS学习笔记-自己动手写RESideMenu
代码地址如下:http://www.demodashi.com/demo/11683.html 很多app都实现了类似RESideMenu的效果,RESideMenu是Github上面一个stars数 ...
- iOS学习笔记——AutoLayout的约束
iOS学习笔记——AutoLayout约束 之前在开发iOS app时一直以为苹果的布局是绝对布局,在IB中拖拉控件运行或者直接使用代码去调整控件都会发上一些不尽人意的结果,后来发现iOS在引入了Au ...
- iOS学习笔记-精华整理
iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始 ...
- iOS学习笔记10-UIView动画
上次学习了iOS学习笔记09-核心动画CoreAnimation,这次继续学习动画,上次使用的CoreAnimation很多人感觉使用起来很繁琐,有没有更加方便的动画效果实现呢?答案是有的,那就是UI ...
- iOS学习笔记总结整理
来源:http://mobile.51cto.com/iphone-386851_all.htm 学习IOS开发这对于一个初学者来说,是一件非常挠头的事情.其实学习IOS开发无外乎平时的积累与总结.下 ...
- IOS学习笔记(四)之UITextField和UITextView控件学习
IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...
随机推荐
- [置顶] android 自定义圆角ImageView以及锯齿的处理
看到很多人开发过程中要使用圆角图片时,解决方法有: 1.重新绘制一张图片 2.通过布局来配置 3.通过重写View来实现 其中1,2在这里就不讲了,重点讲讲方法三的实现. 实现一:通过截取画布一个圆形 ...
- BigDecimal类的简单使用方法
一提到Java里面的商业计算,我们都知道不能用float和double,由于他们无法进行精确计算.可是Java的设计者给编程人员提供了一个非常实用的类BigDecimal,他能够完好float和dou ...
- Javascript 基础编程练习一
Javascript 基础互动编程,这篇练习结合了function 函数名(), onclick 时间, prompt输入窗口, window.open和confirm窗口, 任务 1.新窗口打开时弹 ...
- JavaScript引用类型之Array数组的排序方法
数组中已经存在两个JavaScript给我们定义好的重排序的方法:reverse()和sort()方法,下面来简单分析下: 1.reverse() 用于反转数组项的顺序,代码如下: <sc ...
- 数据库值N'string'
加上 N 代表存入数据库时以 Unicode 格式存储.N'string' 表示string是个Unicode字符串 Unicode 字符串的格式与普通字符串相似,但它前面有一个 N 标识符(N 代表 ...
- js 模拟java 中 的map
//js模拟map Map = { obj : {}, put : function(key , value){ this.obj[key] = value; }, get : function(ke ...
- iOS中点击背景收键盘
这一次给大家带来的是ios中点击背景如何收键盘(感觉不错给个赞
- php 前端获取数据
<pre name="code" class="python"><!doctype html> <html lang=" ...
- SPOJ 220 Relevant Phrases of Annihilation(后缀数组+二分答案)
[题目链接] http://www.spoj.pl/problems/PHRASES/ [题目大意] 求在每个字符串中出现至少两次的最长的子串 [题解] 注意到这么几个关键点:最长,至少两次,每个字符 ...
- 11136-Hoax or what
Each Mal-Wart supermarket has prepared a promotion scheme run by the following rules: A client who w ...