多控制器(UINavigationController)和控制器的生命周期

"【导航控制器】"

(1)导航控制器是用来管多个子控制器,实现不同界面间的 "来回切换",系统的界面就是一个导航控制器

(2)掌握代码创建导航控制器及设置根控制器

(3)掌握如何进入到下一个控制器、返回上一个控制器、返回第一控制器

 

(4)理解导航控制器的view的结构//详情见PPT

  * ios7之后,包括ios7的导航控制器结构

状态栏先放到上面,导航控制器的view放在窗口上(和窗口一样,状态栏的颜色和导航控制器的view的颜色一样,因为被同化),而栈顶控制器的view全部放到导航控制器上面(和窗口一样大小)。导航条也放到上面.说明栈顶控制器的view在导航控制器的view和导航条中间。

  * ios6以前,包括ios6的导航控制器结构

导航控制器的view放在窗口上留有空隙,是放状态栏的。导航条放在导航控制器上面,紧挨着状态栏,而栈顶控制器(根控制器)的view放在导航条下面。

 

(5)掌握导航控制器显示各个子控制器显示的的原理 //栈顶原理

/**

 栈顶原理

 0.导航控制器将所要显示的子控制器放到一个栈中

 1.导航控制器显示的第一个控制器为栈顶控制器

 2.返回上一个子控制器时,栈顶控制器的view从导航控制器的view中移除,并栈顶控制器将被销毁

 3.把最新的栈顶控制器的view显示在导航控制器view的上面

 4.所有的子控制器会存储在导航控制器的viewControllers属性中

 */

 

(6)掌握导航控制器中导航栏左右两边的按钮与标题的设置

  * 每一个控制器有个navigationItem属性

  * 使用navigationItem可设置标题

  * 设置标题还可以使用控制器的title属性

  * 使用navigationItem还可设置左右两边的按钮

  * 设置返回按钮,当前控制器设置的返回按钮是给下一个控制器显示的

  * navigationItem还有个titleView属性,可添加自己义的标题

(7)设置导航栏的带图片的返回按钮

 多控制器(手写代码)

AppDelegate.m

#import "AppDelegate.h"

#import "OneViewController.h"

@interface AppDelegate ()

 

@end

 

@implementation AppDelegate

 

 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Override point for customization after application launch.

    UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    //设置窗口的根控制器为导航控制器

    OneViewController *oneVc = [[OneViewController alloc] init];

    oneVc.view.backgroundColor = [UIColor redColor];

    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:oneVc];

    window.rootViewController = nav;

    self.window = window;

    [window makeKeyAndVisible];

    return YES;

OneViewController.m

#import "OneViewController.h"

#import "TwoViewController.h"

@interface OneViewController ()

- (IBAction)enter;

 

 

 

@end

 

@implementation OneViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view from its nib.

    //设置标题

    //当前控制器有一个navigationItem属性可以设置标题

    self.navigationItem.title = @"第一个控制器";

    self.title = @"第一个控制器";

    

    UIBarButtonItem *cameraItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:nil action:nil];

    UIBarButtonItem *composeItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:nil action:nil];

    self.navigationItem.leftBarButtonItems = @[cameraItem, composeItem];

//    self.navigationItem.rightBarButtonItem = cameraItem;

    //设置返回按钮 代表下一个控制器返回按钮

    UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:nil];

    self.navigationItem.backBarButtonItem = backItem;

}

TwoViewController.m

#import "TwoViewController.h"

#import "ThreeViewController.h"

@interface TwoViewController ()

- (IBAction)backVc;

- (IBAction)enterThree;

 

@end

 

@implementation TwoViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    //设置返回按钮 代表下一个控制器返回按钮

    UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@"返回1" style:UIBarButtonItemStylePlain target:nil action:nil];

    self.navigationItem.backBarButtonItem = backItem;

    //希望下一个控制器的返回按钮是一张图片

    //通过下面的方法没法设置

//    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"btn_back_normal@2x"] style:UIBarButtonItemStylePlain target:nil action:nil];

//    self.navigationItem.backBarButtonItem = item;

   //自定义按钮设置在返回按钮是无效

//    UIButton *btn = [[UIButton alloc] init];

//    btn.bounds = CGRectMake(0, 0, 46, 31);

//    [btn setBackgroundImage:[UIImage imageNamed:@"btn_back_normal"] forState:UIControlStateNormal];

//    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:btn];

//    self.navigationItem.backBarButtonItem = item

//    ;

}

- (IBAction)back {

}

 

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

 

-(void)dealloc

{

    NSLog(@"%s", __func__);

}

ThreeViewController.m

#import "ThreeViewController.h"

 

@interface ThreeViewController ()

- (IBAction)enterOne;

 

@end

 

@implementation ThreeViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view from its nib.

    UIButton *btn = [[UIButton alloc] init];

    btn.bounds = CGRectMake(0, 0, 46, 31);

    [btn setBackgroundImage:[UIImage imageNamed:@"btn_back_normal"] forState:UIControlStateNormal];

    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:btn];

    [btn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];

    //设置左边的按钮

    self.navigationItem.leftBarButtonItem = item

    ;

 

}

 

-(void)back

{

    [self.navigationController popViewControllerAnimated:YES];

}

 

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

 

(8)熟练storybaord添加导航控制器

  * 设置导航控制器的根控制器

  * 显示新的控制器,使用push 或者 show

  * 添加导航栏两边按钮

  * 添加自己自定按钮

导航条左右两边的item可以有属性设置System Item;

两个控制器连线是先左按两下视图变灰,然后ctrl+右连。Xcode5push方法,新的连线show,如果用show的话,根控制器与第一个控制器有navigationItem属性,而其他控制器之间没有这个属性,如果添加titleView(用stroybaord)只有在上面加上view ,再加图片。

/*

 *注:

 xcode5,使用storyboard显示 "push" 新的控制器,会在控制器添加个navivationItem

xcode6,使用storyboard显示 "show" 只有在根控制器才会有navigationItem,其它子控制器没navigationItem,需要时就自己添加

 */

 

 OneViewController.m 以及TwoViewController.m,ThreeViewController.m 都类似

#import "OneViewController.h"

 

@interface OneViewController ()

 

@end

 

@implementation OneViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    NSLog(@"one 加载完成");

}

 

-(void)viewWillAppear:(BOOL)animated{

    NSLog(@"one view 将显示");

}

 

-(void)viewDidAppear:(BOOL)animated{

    NSLog(@"one view完成显示");

}

 

-(void)viewWillDisappear:(BOOL)animated{

    NSLog(@"one view将消失");

}

 

-(void)viewDidDisappear:(BOOL)animated{

    NSLog(@"one view已经消失");

}

//iOS6以后,把viewWillUnload/viewDidUnload视为过期,不再调用 "仅做为了解"

-(void)viewWillUnload{

    NSLog(@"one view将卸载");

    self.view = nil;

}

 

-(void)viewDidUnload

{

    NSLog(@"one view已经卸载");

    //清除资源

}

 

//内存警告

- (void)didReceiveMemoryWarning {

    //自觉清除一些必要的内存

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

    NSLog(@"%s",__func__);

}

 

 

@end

 

 

 

"【控制器的生命周期】"

(1)理解控制器的生命周期的几个方法

viewDidLoad //view加载完毕

viewWillAppear//view即将显示

viewDidAppear//view已经显示

viewWillDisappear//view即将消失

viewDidDisappear//view已经消失

viewWillUnload//view即被卸载

viewDidUnload//view已经卸载

dealloc//控制器被销毁

 

 

(2)理解接收到控制器内存警告时在以前中做的事

  * 循问当前哪个view可以卸载,比如当前控制器不在窗口上,就代表不用,就进行卸载view

  * view被卸载完后,清空数据来释放内存给别人用

  * 在非arc环境下清空资源前,会先释放

  * ios6以后,把viewWillUnload/viewDidUnload视为过期,不再调用 "仅做为了解"

  * 查看 "生命周期方法.png" 文件

模拟内存警告,点击模拟器,然后点击Hardware,然后模拟sumulate memorywarning

 

原文地址:https://www.cnblogs.com/Lu2015-10-03/p/5143412.html