多控制器-2

笔记

0_1.jpg
0_1.jpg
1_1.jpg
2_1.jpg
3_1.jpg
05-KVC模型改进-自定义国旗键盘.jpg
06-自定义生日键盘.jpg
07-自定义城市键盘.jpg
08-自定义城市键盘-初始化文字处理-.jpg
09-导航控制器简介.jpg
10-导航控制器View的结构.jpg
11-导航控制器的使用.jpg
12-导航控制器管理原则.jpg
13-设置导航条内容.jpg

Xmind

中心主题.png

PPT

1-控制器管理

  • 控制器以及view的多种创建方式
  • UINavigationController的简单使用:添加\移除子控制器
  • UINavigationBar内容的设置
  • 控制器的生命周期方法
  • Segue的使用
  • 控制器之间数据的传递
  • UITabBarController的简单使用
  • UITabBarController和UINavigationController的混合使用
  • Modal

2-创建控制器

控制器常见的创建方式有以下几种

  • 直接创建
MJViewController *mj = [[MJViewController alloc] init];
  • 指定xib文件来创建
MJViewController *mj = [[MJViewController alloc] initWithNibName:@"MJViewController" bundle:nil];
  • 通过storyboard创建
    • 先加载storyboard文件(Test是storyboard的文件名)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Test" bundle:nil];
  • 接着初始化storyboard中的控制器(两种方式)
    • 初始化“初始控制器”(箭头所指的控制器)
MJViewController *mj = [storyboard instantiateInitialViewController];
   - 通过一个标识初始化对应的控制器
MJViewController *mj = [storyboard instantiateViewControllerWithIdentifier:@”mj"];

3-控制器的View

Snip20170213_196.png
  • 控制器view的延迟加载
  • 控制器的view是延迟加载的:用到时再加载
  • 可以用isViewLoaded方法判断一个UIViewController的view是否已经被加载
  • 控制器的view加载完毕就会调用viewDidLoad方法

4-多控制器的管理

  • 一个iOS的app很少只由一个控制器组成,除非这个app极其简单
  • 当app中有多个控制器的时候,我们就需要对这些控制器进行管理
  • 有多个view时,可以用一个大的view去管理1个或者多个小view
  • 控制器也是如此,用1个控制器去管理其他多个控制器
  • 比如,用一个控制器A去管理3个控制器B、C、D
    • 控制器A被称为控制器B、C、D的“父控制器”
    • 控制器B、C、D的被称为控制器A的“子控制器”
  • 为了便于管理控制器,iOS提供了2个比较特殊的控制器
    • UINavigationController
    • UITabBarController

5-UINavigationController

UINavigationController的view结构

Snip20170213_197.png
Snip20170213_199.png

UINavigationController的简单使用

  • UINavigationController的使用步骤
    • 初始化UINavigationController
    • 设置UIWindow的rootViewController为UINavigationController
    • 根据具体情况,通过push方法添加对应个数的子控制器


      Snip20170213_200.png

UINavigationController的子控制器

  • UINavigationController以栈的形式保存子控制器
    • @property(nonatomic,copy) NSArray *viewControllers;
  • @property(nonatomic,readonly) NSArray *childViewControllers;
  • 使用push方法能将某个控制器压入栈
     -(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
    
- 使用pop方法可以移除控制器
   - 将栈顶的控制器移除

-(UIViewController *)popViewControllerAnimated:(BOOL)animated;

   - 回到指定的子控制器
  • (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;
   - 回到根控制器(栈底控制器)

-(NSArray *)popToRootViewControllerAnimated:(BOOL)animated;


###如何修改导航栏的内容
 - 导航栏的内容由栈顶控制器的navigationItem属性决定
 - UINavigationItem有以下属性影响着导航栏的内容
     - 左上角的返回按钮

@property(nonatomic,retain) UIBarButtonItem *backBarButtonItem;

     - 中间的标题视图

@property(nonatomic,retain) UIView *titleView;

     - 中间的标题文字

@property(nonatomic,copy) NSString *title;

     - 左上角的视图

@property(nonatomic,retain) UIBarButtonItem *leftBarButtonItem;
UIBarButtonItem *rightBarButtonItem 右上角的视图
@property(nonatomic,retain) UIBarButtonItem *rightBarButtonItem;


##6-Segue
- Storyboard上每一根用来界面跳转的线,都是一个UIStoryboardSegue对象(简称Segue)
![Snip20170213_201.png](http://upload-images.jianshu.io/upload_images/1609505-3118d2cb7d70cd51.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###Segue的属性
- 每一个Segue对象,都有3个属性
  - 唯一标识

@property (nonatomic, readonly) NSString *identifier;

 - 来源控制器

@property (nonatomic, readonly) id sourceViewController;

 - 目标控制器

@property (nonatomic, readonly) id destinationViewController;

![Snip20170213_202.png](http://upload-images.jianshu.io/upload_images/1609505-352866aea0422f63.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###Segue的类型
- 根据Segue的执行(跳转)时刻,Segue可以分为2大类型
  - 自动型:点击某个控件后(比如按钮),自动执行Segue,自动完成界面跳转
 - 手动型:需要通过写代码手动执行Segue,才能完成界面跳转

###自动型Segue
- 按住Control键,直接从控件拖线到目标控制器
![Snip20170213_203.png](http://upload-images.jianshu.io/upload_images/1609505-249c5a6f9c9c54c4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 点击“登录”按钮后,就会自动跳转到右边的控制器
- 如果点击某个控件后,不需要做任何判断,一定要跳转到下一个界面,建议使用“自动型Segue”

###手动型Segue
- 按住Control键,从来源控制器拖线到目标控制器
![Snip20170213_204.png](http://upload-images.jianshu.io/upload_images/1609505-892d8d8d07212308.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 在恰当的时刻,使用perform方法执行对应的Segue

[self performSegueWithIdentifier:@"login2contacts" sender:nil];
// Segue必须由来源控制器来执行,也就是说,这个perform方法必须由来源控制器来调用

- 如果点击某个控件后,需要做一些判断,也就是说:满足一定条件后才跳转到下一个界面,建议使用“手动型Segue”

###performSegueWithIdentifier:sender:方法
- 利用performSegueWithIdentifier:方法可以执行某个Segue,完成界面跳转
- 接下来研究performSegueWithIdentifier:sender:方法的完整执行过程
[self performSegueWithIdentifier:@“login2contacts” sender:nil];
// 这个self是来源控制器
 - 根据identifier去storyboard中找到对应的线,新建UIStoryboardSegue对象
   - 设置Segue对象的sourceViewController(来源控制器)
   - 新建并且设置Segue对象的destinationViewController(目标控制器)
![Snip20170213_205.png](http://upload-images.jianshu.io/upload_images/1609505-e9e451f60894d6ca.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
 - 调用sourceViewController的下面方法,做一些跳转前的准备工作并且传入创建好的Segue对象
  • (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;
    // 这个sender是当初performSegueWithIdentifier:sender:中传入的sender
 - 调用Segue对象的- (void)perform;方法开始执行界面跳转操作
    - 如果segue的style是push
         - 取得sourceViewController所在的UINavigationController
         - 调用UINavigationController的push方法将destinationViewController压入栈中,完成跳转
   - 如果segue的style是modal
        - 调用sourceViewController的presentViewController方法将destinationViewController展示出来

###Sender参数的传递

[self performSegueWithIdentifier:@“login2contacts” sender:@“jack”];

  • (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;

##7-控制器的数据传递
- 控制器之间的数据传递主要有2种情况:顺传和逆传
   - 顺传
       - 控制器的跳转方向: A->C
       - 数据的传递方向    : A -> C
       - 数据的传递方式    :  在A的prepareForSegue:sender:方法中根据segue参数取得destinationViewController, 也就是控制器C, 直接给控制器C传递数据
(要在C的viewDidLoad方法中取得数据,来赋值给界面上的UI控件)
![Snip20170213_206.png](http://upload-images.jianshu.io/upload_images/1609505-54f54004954ecffa.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
   - 逆传
       - 控制器的跳转方向: A ->C
       - 数据的传递方向    : C ->A
       - 数据的传递方式    :  让A成为C的代理, 在C中调用A的代理方法,通过代理方法的参数传递数据给A
![Snip20170213_207.png](http://upload-images.jianshu.io/upload_images/1609505-6627469cc74c3cdb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

##8-UITabBarController
###UITabBarController的简单使用
- UITabBarController的使用步骤
   - 初始化UITabBarController
   - 设置UIWindow的rootViewController为UITabBarController
   - 根据具体情况,通过addChildViewController方法添加对应个数的子控制器

###UITabBarController的子控制器
- UITabBarController添加控制器的方式有2种
   - 添加单个子控制器
- (void)addChildViewController:(UIViewController *)childController;

  - 设置子控制器数组

@property(nonatomic,copy) NSArray *viewControllers;


###UITabBarController的view结构
![Snip20170213_208.png](http://upload-images.jianshu.io/upload_images/1609505-4f545988d072bdf8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

![Snip20170213_209.png](http://upload-images.jianshu.io/upload_images/1609505-4c426df4a432b08f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###UITabBar
- 如果UITabBarController有N个子控制器,那么UITabBar内部就会有N个UITabBarButton作为子控件
- 如果UITabBarController有4个子控制器,那么UITabBar的结构大致如下图所示
![Snip20170213_210.png](http://upload-images.jianshu.io/upload_images/1609505-715ec44decd224aa.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###UITabBarButton
![Snip20170213_211.png](http://upload-images.jianshu.io/upload_images/1609505-05c4840455efa8f4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###App主流UI框架结构
![Snip20170213_212.png](http://upload-images.jianshu.io/upload_images/1609505-32a56168578f76c1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###Modal
- 除了push之外,还有另外一种控制器的切换方式,那就是Modal
- 任何控制器都能通过Modal的形式展示出来
- Modal的默认效果:新控制器从屏幕的最底部往上钻,直到盖住之前的控制器为止
- 以Modal的形式展示控制器
  • (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion
- 关闭当初Modal出来的控制器
  • (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion;
![Snip20170213_213.png](http://upload-images.jianshu.io/upload_images/1609505-e89d68e15fa388d4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###9-图片
![控制器view加载.png](http://upload-images.jianshu.io/upload_images/1609505-5bafac4a1e751f6f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

![内存警告处理.png](http://upload-images.jianshu.io/upload_images/1609505-f989f56d665128f5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

![生命周期方法.png](http://upload-images.jianshu.io/upload_images/1609505-ddf7ebcfa8ea0eae.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

#总结

1.loadView方法作用以及注意点有哪些?
作用:控制器会调用方法去创建控制器的View.
什么时候调用:当第一次使用控制器的View
开发中loadView使用场景:自定义控制器的View.
1.一旦重写了loadView,表示需要自己创建控制器的View.
2.如果控制器的View还没有赋值,就不能调用控制器View的get方法.会造成死循环.因为控制器View的get方法底层会调用loadView方法.

2.KVC底层实现?
setValue:obj forKeyPath:key的底层实现:
1.它会调用这个属性的set方法.
2.如果没有set方法,它会去判断有没有跟key值同名的成员属性.如果有,就直接赋值.icon = obj.
3.如果没有,那么它还会去判断有没有跟key值名相同带有下划线的成员属性,如果有,就直接赋值,_icon = obj.
4.如果都没有, 就直接报错.找不到对应的成员属性.

3.控制器View懒加载是什么意思?
什么时候用到控制器View的时候,才会调用loadView方法创建控制器的View

4.导航控制器管理原则?
1.当调用导航控制器的push方法时, 就会把一个控制器压入到导航控制器的栈中, 那么刚压入栈中的这个导航控制器就在栈的最顶部.
2.它就会把原来导航控制器View当中存放的子控制器View的内容移除,然后把导航控制器栈顶控制器的View添加到导航控制器专门存放子控制器View当中.
3.注意:只是把控制器的View从导航控制器存放子控制器的View当中移除,并没有把控制器从栈中移除.所以上一个控制器还在.
4.当调用pop当方法时, 就会把导航控制器存放子控制器View当中控制器的View移除,并且会把该控制器从栈里面移除.
5.此时该控制器就会被销毁.接着它就会把上一个控制器的View添加到导航控制器专门存放子控制器的View当中.

5.如果设置导航条内容?
设置导航条的内容,由栈顶控制器的NavgationItem决定.

6.事件是怎么样产生与传递的?
1.当发生一个触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中.
2.UIApplication会从事件队列中取出最前面的事件,将事件传递给主窗口
3.主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件
4.触摸事件的传递是从父控件传递到子控件的.
5.如果一个父控件不能接收事件,那么它里面的了子控件也不能够接收事件.

7.一个控件什么情况下不能够接收事件?
1.不接收用户交互时不能够处理事件:userInteractionEnabled = NO
2.当一个控件隐藏的时候不能够接收事件:Hidden = YES的时候
3.当一个控件为透明白时候也不能够接收事件:alpha <= 0.01

8.如果寻找最适合的View?
1.先判断自己是否能够接收触摸事件,如果能再继续往下判断,
2.再判断触摸的当前点在不在自己的身上.
3.如果在自己身上,它会从后往前遍历子控件,遍历出每一个子控件后,重复前面的两个步骤.
4.如果没有符合条件的子控件,那么它自己就是最适合的View.

9.事件传递与响应的完整过程是什么?
1.先将事件对象由上往下传递(由父控件传递给子控件),找到最合适的控件来处理这个事件。
2.调用最合适控件的touches….方法
3.如果调用了[super touches….];就会将事件顺着响应者链条往上传递,传递给上一个响应者
4.接着就会调用上一个响应者的touches….方法

10.如何判断上一个响应者
1.如果当前这个view是控制器的view,那么控制器就是上一个响应者
2.如果当前这个view不是控制器的view,那么父控件就是上一个响应者

11.UIApplication作用?
1.设置应用提醒数字
2.设置连网状态
3.设置状态栏
4.跳转网页

12.应用程序的程动原理
1.执行Main
2.执行UIApplicationMain函数.
3.创建UIApplication对象,并设置UIApplicationMain对象的代理.
4.开启一个主运行循环.保证应用程序不退出.
5.加载info.plist.加载配置文件.判断一下info.plist文件当中有没有Main storyboard file base name,里面有没有指定storyboard文件,

13.如何创建UIWindow?
1.创建窗口
2.创建控制器
3.设置控制器为窗口的根控制器
4.显示窗口

14.push与show的区别(push与show方法只有在有导航控制器下才有效)
1.push这个方法过期了,通过StoryBoard跳转控制器,从一个控制器的界面按住ctrl拖向下一个控制器,运行时可以从当前控制器跳转到下一个控制器。
2.show方法也是一样,功能相同但他是个新方法,在iphone设备上show显示的是一个控制器窗口,但在ipad的上显示的是两个窗口,一个正常窗口一个是详情页窗口。
3.-viewDidLoad方法在view的整个生命周期中只会调用一次,所以在这个方法里面可以加载子控件和加载网络数据请求
4.-viewWillAppear和-viewWillDisAppear方法里面设置view即将显示时和即将消失时需要设置的操作,这两个方法多次调用

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容