UI day 8 导航控制器 属性传值 代理传值 单例传值

                                             导航控制器    
1.  UINavigationController是导航控制器,是用来管理多个单视图控制器的控制器,此时它管理的多个单视图控制之间有一定得层级关系,(依赖关系,下一个页面的出现要依赖于上一个页面)。导航视图控制器创建时也会自带一个View只不过此时它的上面有两个子视图,一个是contentview,一个是navigationBar,管理的多个单视图控制器自带的View,都添加到contentview,导航控制器在完成页面间跳转的时候,是一个不断创建和销毁的过程

UINavigationController在管理视图的时候使用的栈的数据结构,进入下一界面入展,此时要创建下一级页面视图,返回上一级页面就是出栈,此时会把当前的视图界面给销毁

//创建单视图控制器
   
FirstViewController *firstVC = [[FirstViewController alloc]init];
   
//    创建导航控制器对象
//    firstvc 指定为导航视图控制器的根视图的控制器
   
UINavigationController  *navigationVC =[[UINavigationController alloc]initWithRootViewController:firstVC];
   
self.window.rootViewController = navigationVC;
    [firstVC
release];
    [navigationVC
release];
    当界面的切换的时候,两个视图控制器AB视图的现实和消失的过程
 
AB(从前到后)
 A
ViewwilldisAppear---BviewWillAppear-->A(viewDiddisAppear:)--->B(viewDidAppear:)
 
ba从后到钱
 BViewwilldisAppear---AviewWillAppear-->B(viewDiddisAppear:)--->A(viewDidAppear:)
2.
//视图将要出现的时候触发
- (
void)viewWillAppear:(BOOL)animated
{
   
NSLog(@"%s",__FUNCTION__);
}
//视图已近出现的时候
- (
void)viewDidAppear:(BOOL)animated
{
   
NSLog(@"%s",__FUNCTION__);
}
//视图机将要消失
- (
void)viewWillDisappear:(BOOL)animated
{
   
NSLog(@"%s",__FUNCTION__);
}
//视图已经消失的时候触发
- (
void)viewDidDisappear:(BOOL)animated
{
   
NSLog(@"%s",__FUNCTION__);
}


- (void)viewDidLoad {
    [
super viewDidLoad];
   
self.view.backgroundColor = [UIColor orangeColor];
   
//调用配置导航条的颜色
    [
self configureCommonProperty];
//    调用界面导航条独有的
    [
self customNavigationItemAppearance];
   
   
UIButton *pusButton = [UIButton buttonWithType:(UIButtonTypeSystem)];
   
    pusButton.
frame = CGRectMake(20, 64, 280, 40);
    [pusButton
setTitle:@"进入下一个页面" forState:(UIControlStateNormal)];
    [pusButton
addTarget:self action:@selector(handlePush:) forControlEvents:(UIControlEventTouchUpInside)];
    pusButton.
backgroundColor = [UIColor redColor];
    [
self.view addSubview:pusButton];
   
   
}


3.
- (
void)handlePush:(UIButton *)push
{
//2.   创建SecondViewController对象
   
   
SecondViewController *secondVC =[[SecondViewController alloc]init];
   
//3.获取导航视图控制器并完成跳转
   
//4.self.navigationController获取当前视图的导航控制器对象
   
//第一个参数:待跳转得视图控制器对象
   
//第二个参数:是否需要动画
    [
self.navigationController pushViewController:secondVC animated:YES];
   
//4.释放
    [secondVC
release];
   
   
NSLog(@"push");
   
}

//配置导航条公共的属性,该属性作用于所有的界面
- (
void)configureCommonProperty
{
   
//设置导航条的颜色
   
self.navigationController.navigationBar.barTintColor = [UIColor yellowColor];
//  控制导航条的毛玻璃效果是否打开,影响的是contentview上视图的布局
   
self.navigationController.navigationBar.translucent = YES;
//    设置导航条是否隐藏
   
self.navigationController.navigationBarHidden = NO;
//    设置导航条内容的颜色(标题,视图边框的颜色)
   
self.navigationController.navigationBar.tintColor =[UIColor orangeColor];
   
//设置导航条的背景颜色
   
//44的高的图片只在导航条上  64高的时导航条和状态栏都有  其他情况拉伸或者压缩
    [
self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"1"] forBarMetrics:(UIBarMetricsDefault)];
}

4.
//针对于每个界面单独定制导航条上的内容
- (
void)customNavigationItemAppearance
{
//  1.  配置导航条显示的标题
  
self.navigationItem.title = @"FirstVC";
//  2. 配置导航条的标题视图
   
UISegmentedControl  *segmentView = [[UISegmentedControl alloc]initWithItems:@[@"所有通话",@"未接来电"]];
   
self.navigationItem.titleView = segmentView;
    [segmentView
release];
//  3.配置导航条的左右按钮
//   
   
UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]initWithTitle:@"+" style:(UIBarButtonItemStylePlain) target:self action:@selector(handleLeftItem:)];
   
self.navigationItem.leftBarButtonItem = leftItem;
    [leftItem
release];
   
//
   
UIBarButtonItem  *rightItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:(UIBarButtonSystemItemTrash) target:self action:@selector(handleRightItem:)];
   
self.navigationItem.rightBarButtonItem = rightItem;
}



#pragma mark 实现左barButton的方法
- (void)handleLeftItem:(UIBarButtonItem *)leftItem
{
   
NSLog(@"添加");
}
5.
//针对于每个界面单独定制导航条上的内容
- (
void)customNavigationItemAppearance
{
   
//    配置导航条显示的标题
   
self.navigationItem.title = @"ThirdVC";
}


//1.返回上一级界面,也是由导航视图控制器完成
//   
//    [self.navigationController popViewControllerAnimated:YES];
//   
//    NSLog(@"pop");
   
//   2. 返回到导航视图控制器的根视图控制器对象
   
//    [self.navigationController popToRootViewControllerAnimated:YES];
   
//    3. 返回到指定的视图控制器##################################################
//    方法一      获取导航视图控制器的所有单视图控制器
    NSArray *controllArray = self.navigationController.viewControllers;
   
//返回到指定的视图控制器
    [
self.navigationController popToViewController:controllArray[1] animated:YES];
      方法二
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];
//针对于每个界面单独定制导航条上的内容
- (
void)customNavigationItemAppearance
{
   
//    配置导航条显示的标题
   
self.navigationItem.title = @"ForthVC";
}


        ##################对上面方法的总结#################

可以手动设置pop出栈,相当于删除这个页面,跳转到其他页面
//popViewControllerAnimated就是弹出,因为弹出只能弹出最上面的栈顶的那个,所以可以不用指定参数
//popToRootViewControllerAnimated-就是直接跳转到根视图控制图,如果只有两层,那么和popViewControllerAnimated并无区别,如果有很多层,那么其实就是相当于不仅把自己pop出去,还把所有除了根视图控制图之外的所有视图控制器都pop出去了,所以就相当于跳转到根视图控制器了
//popToViewController-就是跳转到指定的视图控制器xxx,这个xxx一定要在这个栈里面,即一定是在我们当前这个视图控制器的下面的,所以跳转也就是把自己和在xxx上面的所有视图控制器都pop出去,然后相当于直接跳转到xxx
//此处重点是这个xxx怎么获取,按照一般理解是用xxx再初始化一个视图控制器对象yyy,然后把这个对象yyy作为popToViewController参数
//但事实是,yyy是新初始化的,不在栈中,当然和在栈中的xxx初始化的那个对象也不是同一个对象,所以会报错(因为在栈中找不到啊)
//所以,self.navigationController.viewControllers出场,viewControllers是个数组,储存的时导航控制器栈中所有的视图控制器,最先push进去的时0,以此类推,最上面的肯定是数组的最后一个
//所以,那个xxx之前初始化的对象,可以用[self.navigationController.viewControllers objectAtIndex:0]表示,此处0就是根视图控制器
//所以,只要拿到navigationController,貌似能做很多事情

                                                  属性传值
1.从前一个页面到后一个页面传值       葵花宝典 :属性传值   
属性传值 的步骤:
第一步:在下一个视图控制器.h文件定义一个属性
第二步:在push之前将数据存储到属性中
第三步:取出属性中的值让控件显示
      firstView           secondView  这是两个单视图控制器
(1)#warning 属性传值第一步   定义属性,且属性的类型要和传人的数据类型保持一致在下一个.h中定义
  也就是在secondView.h中定义属性
@property(nonatomic,copy)NSString *textString;

  - (void)handleButton:(UIButton *)button
{  
此时创建的是下一个界面对象
SecondViewController *secondVC = [[SecondViewController alloc]init];
(2)#warning 属性传值的第二步 push之前传人数据  在firstView.m中写
secondVC. textString   = (( UITextField *)[ self . view viewWithTag : 200 ]). text ;
[ self . navigationController pushViewController :secondVC animated : YES ];
[secondVC release];
}

- (void)viewDidLoad {
    [
super viewDidLoad];
   
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(20, 100, 280, 40)];
    label.
backgroundColor = [UIColor yellowColor];
  
    label.
text = @"给我上一个页面的内容";
(3)#warning 属性传值的第三步 取出数据让控件显示 在secondView.m中写
    label.text = _textString;
    [
self.view addSubview:label];
    [label
release];
   

                                             代理传值
1.从后一个页面往前一个页面传值      辟邪剑谱  :代理传值
代理传值的步骤:
第一步:制定协议
第二步:定义代理属性
第三步:在外界指定代理
第四步:代理要遵循协议
第五步:代理要实现协议中方法
第六步:让代理执行协议中的方法
firstView      secondView   这是两个单视图控制器

(1)#warning 代理传值第一步 定义协议  在secondView.h中写
@protocol SecondViewControllerDelegate <NSObject>

(2)#warning 代理传值第二步  定义代理属性 在secondView.h中写
@property ( nonatomic , assign ) id < SecondViewControllerDelegate >delegate;

- (void)handleButton:(UIButton *)button
{
  //此时创建的是下一个界面对象
SecondViewController *secondVC = [[ SecondViewController alloc ] init ];
(3)#warning 代理传值的第三步  为后一个界面指定代理对象,只能是前一个视图控制器对象 在firstView.m中写
    secondVC. delegate = self ;
    [self.navigationController pushViewController:secondVC animated:YES];
    [secondVC
release];
}

(4)#warning 代理传值的第四步 代理对象所在的类遵循协议  在firstView.m中写
@interface FirstViewController ()<SecondViewControllerDelegate>

(5)#warning 代理传值的第五步   实现协议中的方法 在firstView.m中写
-(void)passValue:(NSString *)string
{
    ((UILabel *)[self.view viewWithTag:300]).text = string
}
- (void)handlepopButton:(UIButton *)button
{
(6)#warning 代理传值的第六步  让代理执行协议中的方法
NSString *string = (( UITextField *)[ self . view viewWithTag : 200 ]). text ;
if ([self.delegate respondsToSelector:@selector(passValue:)])
{  [self.delegate passValue:string];
}
    [self.navigationController popViewControllerAnimated:YES];
}



                                           单例传值       
1.能从最后一个页面把值传到最前面    化功大法 :单例传值
单例传值的步骤:
第一步:定义单例类继承NSobject
第二步:定义单例类的创建方法
第三步:实现创建的方法
第四步:定义属性,存储传输数据,属性的类型和传输数据类型必须保持一致
第五步:给单例对象的属性赋值
第六步:取出单例的属性中存储的数据,赋值给控件

(1)#warning  单例传值的第一步  定义单例类继承NSobject 在自己重新创建的类.h中写
   @interface SingleLeton : NSObject
(2)#warning 单例传值的第二步 定义单例类的创建方法  在自己重新创建的类.h中写
#################share stand main 创建单例对象方法一般常用的开头##################
+ (SingleLeton *)shareSingleLeton;

(3)#warning 单例传值的第三步   在自己重新创建的类.m中实现方法
//定义一个由static修饰的singLeton对象
//static修饰的变量的生命周期和应用程序的生命周期一样长,只有程序退出后台的时候才被销毁;单例多用在数据库中
static SingleLeton *single = nil;

+(
SingleLeton *)shareSingleLeton
{
   
//single等于nil时还没有初始化,所以在if语句对其初始化
   
//实时同步单例对象的创建,保护其在多线程下的安全
   
@synchronized(self){
   
if (single == nil) {
       
single = [[SingleLeton alloc]init];
    }
}
   
return single;
}

- (
void)dealloc
{
   
self.string = nil;
    [
super dealloc];
}







(4)#warning 单例传值的第四步  定义属性,存储传输的数据,属性的类型要和传输数据保持一致 在自己重新创建的类.h中写
@property ( nonatomic , copy ) NSString *string;
- (void)handleButton:(UIButton *)button
{
(5)#warning 单例传值的第五步   给单例对象的属性赋值  在单视图控制器的最后一个视图控制器.m中写
    [SingleLeton shareSingleLeton].string = ((UITextField *)[self.view viewWithTag:200]).text;
    [
self.navigationController popToRootViewControllerAnimated:YES];
}

这个一个方法视图将要出现的时候触发
-( void )viewWillAppear:( BOOL )animated{
(6)#warning 单例传值的第六步 取出单例中属性中存储的数据,赋值给控件  在单视图控制器的第一个视图控制器.m中写
 (( UILabel *)[ self . view viewWithTag : 300 ]). text = [ SingleLeton shareSingleLeton ]. string ;

}



















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值