ui进阶第二天,一些琐碎的东西

主要知识点:


**************** 今天的主要知识点 ****************

        1. 控制器及View的多种创建方式


        2. 多控制器管理。

**************** 今天的主要知识点 ****************


    一、复习。

        * 四个对象的关系:

            1> UIApplication


            2> AppDelegate


            3> UIWindow


            4> UIViewController


        * 复习一下程序启动的过程。


        * UIWindow相关:

        * 新建一个"空项目"

            1. 自己手动创建UIWindow, 设置背景色, 运行看效果。


            2. AppDelegate代理对象再加一个window2属性, 再创建一个window对象, 设置不同的颜色、大小, 并调用makeKeyAndVisible方法。


            ** 注意: 当多个UIWindow对象都调用了makeKeyAndVisible方法, 那么最后一个调用该方法的Window将会成为主窗口。


            ** 注意: 一个应用程序同时只能有一个"Key Window"。在iOS 6下只有Key Window上的文本框才能输入内容。


            /** 参考代码: 创建两个UIWindow, 同时显示。

             

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

                 

                     // 创建一个UIWindow

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

                     

                     self.window.backgroundColor = [UIColor blueColor];

                     

                     [self.window makeKeyAndVisible];

                     

                     

                     // 创建第2UIWindow

                     self.window2 = [[UIWindow alloc] initWithFrame:CGRectMake(50, 150, 300, 300)];

                     

                     self.window2.backgroundColor = [UIColor redColor];

                     

                     [self.window2 makeKeyAndVisible];

                     

                     

                     // 输出当前总的UIWindow

                     // NSLog(@"个数: %ld", [UIApplication sharedApplication].windows.count);

                     

                     UIApplication *app =  [UIApplication sharedApplication];

                     

                     // 输出每个UIWindow的地址

                     NSLog(@"%p---%p", self.window, self.window2);

                     

                     // 输出当前"Window的地址"

                     NSLog(@"%p",app.keyWindow);

                     

                     // 输出所有的UIWindow

                     NSLog(@"=====%@=======", app.windows);

                     

                     return YES;

                 }


             

             */



        * 通过调用[UIApplication sharedApplication].keyWindow来获取当前的"主窗口"


            * [self.window makeKeyWindow]; // 设置当前self.window为主窗口。默认只有一个window, 但是可以创建多个window对象。


            * [self.window makeKeyAndVisible]; // 设置当前self.window为主窗口, 并且显示当前窗口。


            * [UIApplication sharedApplication].windows, 获取所有的window

                * 平时输入内容的键盘, 就在一个独立的window中。


                * 动态创建一个按钮, 当单机按钮的时候, 打印一下[UIApplication sharedApplication].windows的个数, 观察有几个Window


                ** 注意: 因为键盘在一个独立的UIWindow, 所以当我们要获取键盘上的按钮的时候, 要首先获取键盘所在的UIWindow对象。


                /** 参考代码: 弹出键盘后, 再观察当前的总的UIWindow的个数。

                 

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

                 

                     // 创建一个UIWindow

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

                     

                     self.window.backgroundColor = [UIColor blueColor];

                     

                     [self.window makeKeyAndVisible];

                     

                     

                     // 创建第2UIWindow

                     self.window2 = [[UIWindow alloc] initWithFrame:CGRectMake(50, 150, 300, 300)];

                     

                     self.window2.backgroundColor = [UIColor redColor];

                     

                     [self.window2 makeKeyAndVisible];

                     

                     

                     NSLog(@"个数: %ld", [UIApplication sharedApplication].windows.count);

                     

                     // 动态创建一个文本框

                     UITextField *txt = [[UITextField alloc] initWithFrame:CGRectMake(20, 20, 100, 20)];

                     txt.borderStyle = UITextBorderStyleRoundedRect;

                     [self.window2 addSubview:txt];

                     

                     // 动态创建一个按钮

                     UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];

                     [btn setTitle:@"点我一下" forState:UIControlStateNormal];

                     btn.frame = CGRectMake(150, 5, 100, 30);

                     

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

                     

                     [self.window2 addSubview:btn];

                     

                     NSLog(@"个数: %ld", [UIApplication sharedApplication].windows.count);

                     

                     return YES;

                 }

                     

                 - (void)btnClick

                 {

                     // 输出当前总的UIWindow

                     NSLog(@"个数: %ld", [UIApplication sharedApplication].windows.count);

                     NSLog(@"%@", [UIApplication sharedApplication].windows);

                 }


                 

                 

                 */




    二、 **** 控制器以及view的多种创建方式 ****(重点掌握)


        ** 了解创建控制器的多种不同方式, 目的是为了后续学习"多控制器管理"打基础。先知道了如何通过多种不同的方式来创建控制器, 然后再进行多控制器的管理。


        1. 控制器(ViewController)管理 (全部创建一个空项目来演示)

            * 创建控制器, 主要有3中方式:

                1> 直接通过alloc + init的方式创建。 然后设置self.window.rootViewController为这个控制器

                    /** 参考代码:

                        思路:

                            1> 创建一个"Single View Application", 删除默认控制器、Main.storyboardMain Interface设置为空。

                     

                            2> 创建一个自定义的控制器, FirstViewController

                     

                            3> AppDelegateapplication: didFinishLaunchingWithOptions:方法中:

                                3.1 创建UIWindow对象。

                     

                                3.2 通过alloc + init的方式创建该控制器的对象, 并设置该控制器View的背景色。

                     

                                3.2 设置UIWindow的根控制器为该控制器对象。

                     

                        =============================== 代码 ======================================

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

                             // 创建UIWindow

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

                             

                             // 创建控制器

                             SteveZFirstViewController *vc1 = [[SteveZFirstViewController alloc] init];

                             vc1.view.backgroundColor = [UIColor blueColor];

                             

                             // 设置控制器为UIWindow对象的根控制器"rootViewController"

                             self.window.rootViewController = vc1;

                             

                             // 显示UIWindow对象

                             [self.window makeKeyAndVisible];

                             

                             return YES;

                         }

                     

                        =============================== 代码 ======================================

                     

                     */


                2> 通过加载storyboard文件,来创建一个控制器。

                    ** 回忆: 之前有Main.storyboard文件, 并设置Main InterfaceMain的时候, 是系统在程序启动之后, 主动加载Main.storyboard文件, 并创建对应的控制器、UIView然后显示到界面上的。


                    ** 现在: 我们删除了Main.storyboard文件, 也清空了Main Interface的配置。那么现在就需要我们自己创建一个新的storyboard文件(Two.storyboard), 然后自己写代码来加载Two.storyboard文件, 这就是手动通过storyboard文件创建控制器的方式。


                    * 自己新建一个storyboard文件,然后拖一个控制器上去。在AppDelegate中主动去加载该storyboard


                    * 具体步骤如下:


                        1. UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"storyboard的文件名(无需写后缀)" bundle:nil]; // 第二个参数传nil, 表示是mainBundle


                        2. [storyboard instantiateInitialViewController]; // 创建storyboard中的 initial view controller


                        3. 然后设置self.window.rootViewController为这个控制器


                        4. storyboard中有多个控制器的时候, 根据控制器的Storyboard ID来创建:

                            [storyboard instantiateViewControllerWithIdentifier:@"vmid"];


                        *** 演示有Main.storyboard文件, 但是没有设置Main Interface, 自己在application:didFinishLaunchingWithOptions:方法中写代码加载Main.storyboard, 并且创建其中的"初始化控制器(Is Initial View Controller)"


                        *** 当要监听控制器中的view中的某个控件的时候, 需要自定义一个控制器类与该控制器相关联, 然后拖线。


                        /** 参考代码:

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

                             

                                 // 0. 创建UIWindow对象

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

                                 

                                 

                                 // ==========================================================================

                                 

                                 // 1. 加载对应的storyboard文件

                                 UIStoryboard *myStoryboard = [UIStoryboard storyboardWithName:@"My" bundle:nil];

                                 

                                 // 2. 创建该storyboard中的被设置为"初始化控制器"(箭头所指向的控制器)的对象。

                                 // UIViewController *vc2 = [myStoryboard instantiateInitialViewController];

                                 

                                 //根据storyboard中的控制器的storyboard ID来创建对应的控制器

                                 UIViewController *vc2 = [myStoryboard instantiateViewControllerWithIdentifier:@"redVwController"];

                                 

                                 // ==========================================================================

                                 

                                 

                                 // 设置控制器为UIWindow对象的根控制器"rootViewController"

                                 self.window.rootViewController = vc2;

                                 

                                 // 显示UIWindow对象

                                 [self.window makeKeyAndVisible];

                                 

                                 return YES;

                             }

                         

                         -------------------------------演示手动加载Main.storyboard-----------------------------------

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

                         

                             // 0. 创建UIWindow对象

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

                             

                             

                             // ==========================================================================

                             

                             // 1. 加载Main.storyboard文件

                             UIStoryboard *myStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

                             

                             // 2. 创建该storyboard中的被设置为"初始化控制器"(箭头所指向的控制器)的对象。

                             UIViewController *vc2 = [myStoryboard instantiateInitialViewController];

                             

                             // ==========================================================================

                             

                             

                             // 设置控制器为UIWindow对象的根控制器"rootViewController"

                             self.window.rootViewController = vc2;

                             

                             // 显示UIWindow对象

                             [self.window makeKeyAndVisible];

                             

                             return YES;

                         }


                         

                         

                         */



                3> 通过指定的xib文件来创建控制器


                    **** 遇到的问题, 直接通过alloc + init 的方式创建控制器, 那么该控制器的view都是空的, 需要完全的自定义(自己通过代码生生View中的所有控件)。这样太麻烦。


                    **** 解决: 自己定义一个xib文件, 创建控制器的时候,通过alloc + initWithNibName来创建。这样创建好的控制器, 就可以使用xib中的view了。


                    **** 注意: 通过xib创建控制器的时候, 必须对xib进行设置, 设置如下:

                            /**

                             

                             

                             // ================ 这两步可以暂时先不设置, 先运行看效果 =======================

                             * 选中xib文件中的"File's Owner", 在属性中设置对应的类(Class)是我们自己建的控制器类。

                                *** "File's Owner"可以理解为, 当前的xib文件是为谁服务的。

                             

                             * 然后选中"File's Owner" -> "右击"选中"view" -> 拖线到对应的View上。(设置该xib文件中哪个视图是控制器默认要创建的视图)

                             // ================ 这两步可以暂时先不设置, 先运行看效果 =======================

                             

                             

                             */



                    * 创建一个自己的控制器类


                    * 创建一个xib文件(注意这个xib文件的名字暂时不要与控制器的名字一样)"Empty.xib"


                    * xib文件中拽一个UIView, 设置view的背景色(便于等会观察)



                    // ================ 这两步可以暂时先不设置, 先运行看效果 =======================

                    * 选中xib文件中的"File's Owner", 在属性中设置对应的类(Class)是我们自己建的控制器类。

                        *** "File's Owner"可以理解为, 当前的xib文件是为谁服务的。


                    * 然后选中"File's Owner" -> "右击"选中"view" -> 拖线到对应的View上。(设置该xib文件中哪个视图是控制器默认要创建的视图)

                    // ================ 这两步可以暂时先不设置, 先运行看效果 =======================



                    * 通过alloc + initWithNibName来创建。


                    /** 参考代码:

                     

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

                     

                         // 创建UIWindow

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

                         

                         // 通过xib文件, 创建控制器

                         SteveZFirstViewController *vc1 = [[SteveZFirstViewController alloc] initWithNibName:@"Empty" bundle:nil];

                         

                         // 设置控制器为UIWindow对象的根控制器"rootViewController"

                         self.window.rootViewController = vc1;

                         

                         // 显示UIWindow对象

                         [self.window makeKeyAndVisible];

                         

                         return YES;

                     }

                     

                     */



         2. 创建控制器中的UIView(参见PPT中的图, 非常重要)


            /**

                    控制器创建好以后, 控制器所管理的View是如何创建的?

                    

                    1> 控制器的View是通过调用控制器的loadView方法来创建的。这个方法是UIViewController中的一个方法。

                        ** 只要控制器的loadView方法被调用了, 那么证明控制器的View创建好了。

             

                    2> 当调用完毕控制器的loadView方法以后, 从这时开始, 才创建好了控制器的view

             

                    3> 当控制器的View被创建好以后, 紧接着就调用控制器的viewDidLoad方法

             

                    4> 控制器的View采用了懒加载的方式, 也就是说, 在需要的使用(在用到的时候)才会创建(调用loadView方法)

             

             ** 注意: 无论控制器是如何创建的, 只要在控制器中, 重写了("实现了"loadView方法, 并且没有调用[super loadView]方法, 那么最终控制器的View就必须完全在loadView方法中自己来创建了。所以loadView方法可以用来自定义View

             

             

             */




                ** 控制器中的View的几种创建方式:


                1. 先介绍self.view是通过loadView来加载的。

                /*

                / 当第一次从self.view中获取view的时候(第一次使用self.view的时候),

                // 控制器会调用它自己的loadView方法先创建一个view, 并且把这个新创建的view设置给self.view, 然后我们就能够通过self.view获取控制器的view

                // 控制器的view, 是通过哪个方法创建出来的。

                // 控制器的view也是通过"懒汉式"来加载的。(控制器的view也是采用懒加载模式)


                @property(nonatomic,retain) UIView *view; // The getter first invokes [self loadView] if the view hasn't been set yet. Subclasses must call super if they override the setter or getter.



                - (void)loadView; // This is where subclasses should create their custom view hierarchy if they aren't using a nib. Should never be called directly.

                 */





/*

 

 //- (void)loadView

 //{

 //    if (如果是直接通过alloc + init方法直接创建的控制器) {

 //        self.view =  [[UIView alloc] init];

 //    } else if (如果是通过storyboard创建的控制器) {

 //        // 加载storyboard中的控制器, 并把storyboard中的控制器设置给self.view

 //    } else if (通过xib创建的控制器) {

 //        // 加载xib中的view, 并把xib中的view设置给self.view

 //    }

 //}

 

 - (void)loadView

 {

 //[super loadView];

 // 如果希望完全自定义一个控制器的view 那么就重写loadView方法, 同时一定不要调用父类的loadView方法。只要调用了父类的loadView方法, 那么就会执行默认的创建控制器的view的行为。

 self.view = [[UIView alloc] init];

 }

 

 */







                    1. 通过storyboard创建, 创建完控制器后, 自动调用loadView方法,创建控制器的view

                        ** 此时自定义的控制器, 因为没有"重写"("实现")loadView方法, 所以loadView方法内部就是根据storyboard文件中的view来创建View的。


                    2. 通过xib文件创建, 创建完控制器后, 自动调用loadView创建控制器的view

                        ** 此时自定义的控制器, 因为没有"重写"("实现")loadView方法, 所以loadView方法内部就是根据storyboard文件中的view来创建View的。


                        ** 通过xib文件创建控制器的时候, 注意xib文件的名字

                            1> 如果创建控制器的时候, 通过initWithNibName指定了xib的名字, 那么就根据该xib创建view


                            2> 如果创建控制器的时候, 没有指定任何xib文件, 也没有相应的storyboard文件, 那么会尝试查找"与控制器名字相同的, 但是去除Controller的文件名的xib文件"。比如: 控制器叫做"CZViewController", 就会查找"CZView.xib"文件, 如果有, 则使用该xib文件创建view(无需手动指定, 系统自动查找)。


                            3> 如果创建控制器的时候, 没有指定任何xib文件, 也没有相应的storyboard文件, 也没有"CZView.xib", 那么会尝试查找与控制器名字完全相同的xib文件。比如: 控制器叫做"CZViewController", 就会查找"CZViewController.xib"文件, 如果有, 则使用该xib文件创建view(无需手动指定, 系统自动查找)。

                        ** 建议: 如果要使用某个xib文件名自动匹配的方式创建view, 建议名字与控制器相同。


                    3. 通过重写(实现)UIViewControllerloadView方法重写。(自己通过代码来创建控制器的View)

                        *** 控制器的loadView方法就是用来自定义View的。

                            ** 如果要为控制器自定义View, 要写在loadView, 不要写在viewDidLoad中。


                        *** 如果重写(实现)loadView方法中调用了[super loadView], 那么依然会使用默认的方式来加载。



                        *** 重写ViewControllerloadView方法,用来自定义View

                            /** 参考代码:

                             

                             // 重写控制器的loadView方法:

                             - (void)loadView

                             {

                                // [super loadView];

                                 self.view = [[UIView alloc] init];

                                 self.view.backgroundColor = [UIColor purpleColor];

                             }

                             

                             */



/*

 通过xib创建view的时候, 如果重写loadView返回的是一个透明的view,不是xib中的view

 - (void)loadView

 {

 [super loadView];

 NSLog(@"loadView");

 //self.view.backgroundColor = [UIColor blueColor];

 }

 */



            ** 注意:无论是通过加载xib创建viewstoryboard创建view, 最终都依赖于loadView方法。


            ** 注意:修改了项目文件(比如:xxx.xib等,要先Product -> Clean, 然后把软件从模拟器中卸载, 然后再运行。)




            ** 如果除非手动指定了xib文件名,则按照该文件来加载,否则如果没有指定任何文件名字,则按照对应的xib文件的命名规则来找对应的xib文件。


            ** 控制器的loadView方法什么时候调用?

                ** 在需要用到控制器的view的时候才调用(当调用UIWindow对象的makeKeyAndVisible方法时,就需要显示该view, 此时就表示用到View了。), 这个就叫做"延迟加载"


                ** 比如当使用self.view.backgroundColor , 要设置控制器的view的背景色时(这时需要用到view了), 那么此时才会开始创建该控制器的view, 也就是说要调用loadView方法了。所以, 如果在loadView方法内部调用self.view.backgroundColor, 就发生死循环了。


            ** 可以通过调用控制器的self.isViewLoaded 方法来判断当前控制器的view是否已经加载完毕了。


            ** 并且当控制器的view加载完毕后, 会调用viewDidLoad方法。



            ** 演示控制器中的View的延迟加载效果(用到的时候才加载。)演示在loadView方法内部使用view,比如self.view.backgroundColor来设置背景色, 此时会发生死循环。

                ** loadView方法, viewDidLoad方法中输出内容。调试看在调用UIWindowmakeKeyAndVisible方法之前,是否会调用这些方法。


                ** 当需要访问view的时候, 调用loadView, 然后调用viewDidLoad方法, 然后才开始使用view



        =====================================UIView复习(所有控件的复习)==================================

        0. 画一个控件的继承关系图。


        1. 凡是继承自UIControl的控件,只要调用addTarget方法就可以监听事件, 无需代理。


        2. UIView的常见属性:

                @interface UIView : UIResponder<NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem>


                /**

                 *  通过一个frame来初始化一个UI控件

                 */

                - (id)initWithFrame:(CGRect)frame;


                // YES:能够跟用户进行交互

                @property(nonatomic,getter=isUserInteractionEnabled) BOOL userInteractionEnabled;  // default is YES


                // 控件的一个标记(父控件可以通过tag找到对应的子控件)

                @property(nonatomic)                                 NSInteger tag;                // default is 0


                // 图层(可以用来设置圆角效果\阴影效果)

                @property(nonatomic,readonly,retain)                 CALayer  *layer;


                @end


                @interface UIView(UIViewGeometry)

                // 位置和尺寸(以父控件的左上角为坐标原点(0, 0))

                @property(nonatomic) CGRect            frame;


                // 位置和尺寸(以自己的左上角为坐标原点(0, 0))

                @property(nonatomic) CGRect            bounds;


                // 中点(以父控件的左上角为坐标原点(0, 0))

                @property(nonatomic) CGPoint           center;


                // 形变属性(平移\缩放\旋转)

                @property(nonatomic) CGAffineTransform transform;   // default is CGAffineTransformIdentity


                // YES:支持多点触摸

                @property(nonatomic,getter=isMultipleTouchEnabled) BOOL multipleTouchEnabled;   // default is NO

                @end


                @interface UIView(UIViewHierarchy)

                // 父控件

                @property(nonatomic,readonly) UIView       *superview;


                // 子控件(新添加的控件默认都在subviews数组的后面, 新添加的控件默认都显示在最上面\最顶部)

                @property(nonatomic,readonly,copy) NSArray *subviews;


                // 获得当前控件所在的window

                @property(nonatomic,readonly) UIWindow     *window;


                // 从父控件中移除一个控件

                - (void)removeFromSuperview;


                // 添加一个子控件(可以将子控件插入到subviews数组中index这个位置)

                - (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;


                // 交换subviews数组中所存放子控件的位置

                - (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2;


                // 添加一个子控件(新添加的控件默认都在subviews数组的后面, 新添加的控件默认都显示在最上面\最顶部)

                - (void)addSubview:(UIView *)view;


                // 添加一个子控件view(被挡在siblingSubview的下面)

                - (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;


                // 添加一个子控件view(盖在siblingSubview的上面)

                - (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;


                // 将某个子控件拉到最上面(最顶部)来显示

                - (void)bringSubviewToFront:(UIView *)view;


                // 将某个子控件拉到最下面(最底部)来显示

                - (void)sendSubviewToBack:(UIView *)view;


                /**系统自动调用(留给子类去实现), 这些方法就可以叫做"事件方法", 由系统调用。**/

                - (void)didAddSubview:(UIView *)subview;

                - (void)willRemoveSubview:(UIView *)subview;


                - (void)willMoveToSuperview:(UIView *)newSuperview;

                - (void)didMoveToSuperview;

                - (void)willMoveToWindow:(UIWindow *)newWindow;

                - (void)didMoveToWindow;

                /**系统自动调用**/


                // 是不是view的子控件或者子控件的子控件(是否为view的后代)

                - (BOOL)isDescendantOfView:(UIView *)view;  // returns YES for self.


                // 通过tag获得对应的子控件(也可以或者子控件的子控件)

                - (UIView *)viewWithTag:(NSInteger)tag;     // recursive search. includes self


                /**系统自动调用(留给子类去实现)**/

                // 控件的frame发生改变的时候就会调用,一般在这里重写布局子控件的位置和尺寸

                // 重写了这个写方法后,一定调用[super layoutSubviews];

                - (void)layoutSubviews;


                @end


                @interface UIView(UIViewRendering)

                // YES : 超出控件边框范围的内容都剪掉

                @property(nonatomic)                 BOOL              clipsToBounds;


                // 背景色

                @property(nonatomic,copy)            UIColor          *backgroundColor; // default is nil


                // 透明度(0.0~1.0)

                @property(nonatomic)                 CGFloat           alpha;                      // default is 1.0


                // YES:不透明  NO:透明

                @property(nonatomic,getter=isOpaque) BOOL              opaque;                     // default is YES


                // YES : 隐藏  NO : 显示

                @property(nonatomic,getter=isHidden) BOOL              hidden;


                // 内容模式

                @property(nonatomic)                 UIViewContentMode contentMode;                // default is UIViewContentModeScaleToFill

                @end


                @interface UIView(UIViewAnimationWithBlocks)

                + (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;

                + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;


                + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations;

                + (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;

                @end





    三、 多控制器管理。

        1. 多控制器的管理的思路: 使用一个控制器来管理所有其他控制器。

            ** 类似于, 使用一个UIView管理其他的的子UIView


        2. 父控制器(管理其他控制器的控制器, 就可以看做是"父控制器") 子控制器(被管理的控制器就是子控制器)


        3. iOS提供了两个比较特殊的控制器(用来管理"控制器"的控制器。):

            * UINavigationController(导航控制器), 轻松管理多个控制器, 并且控制不同控制器之间的跳转和切换。(案例:模拟器中的"设置"

                ** 使用步骤:

                            1> 创建、初始化一个导航控制器: UINavigationController.


                            2> 设置UIWindowrootViewControllerUINavigationController.


                            3> 通过调用push方法添加子控制器到UINavigationController


                            ** 注意:谁是最后一个push进来的,当前显示的就是哪个ViewController


                            /**

                                演示 :

                                        1. 创建完毕UIWindow以后, 创建导航控制器, 然后创建多个普通控制器, push到导航控制器中。调用导航控制器的pushViewController

                             

                             

                                        2. 创建完毕UIWindow以后, 创建导航控制器, 然后创建1个普通控制器, push到导航控制器中。在该控制器的View中增加一个按钮, 当点击按钮的时候, 在创建另外一个控制器, 然后将新控制器push到导航控制器中。

                             

                                        ** 通过当前控制器的navigationController获取当前控制器所在的导航控制器。self.navigationController

                             

                             

                             // 参考代码:

                                 - (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 purpleColor];

                                     

                                     //==============创建导航控制器=========================

                                     UINavigationController *nav = [[UINavigationController alloc] init];

                                     nav.view.backgroundColor = [UIColor greenColor];

                                     self.window.rootViewController = nav;

                                     //==============创建导航控制器=========================

                                     

                                     

                                     UIViewController *item =[[UIViewController alloc] init];

                                     item.view.backgroundColor = [UIColor yellowColor];

                                     [nav pushViewController:item animated:YES];

                                     

                                     UIViewController *item1 =[[UIViewController alloc] init];

                                     item1.view.backgroundColor = [UIColor blueColor];

                                     [nav pushViewController:item1 animated:YES];

                                     

                                     UIViewController *item2 =[[UIViewController alloc] init];

                                     item2.view.backgroundColor = [UIColor redColor];

                                     [nav pushViewController:item2 animated:YES];

                                     

                                     

                                     

                                     [self.window makeKeyAndVisible];

                                     

                                     return YES;

                                 }

                             

                             

                             

                             */



                ** 注意: 导航控制器的导航栏是从Y坐标20开始的, 高度是44。前面的20高度是"状态栏"


                ** 注意: 通过导航控制器UINavigationController切换不同的界面的时候后台做了什么? 点击导航控制器中得Back的时候后台做了什么?


                        ** 添加到导航控制器中的自控制器的View是占满整个屏幕的。


                        ** 参考ppt10 - 18页。


                        ** 点击BACK的时候自动移除栈顶控制器(被移除的控制器会被销毁, 该控制器的view也会被销毁)。


                        ** 导航控制器始终只显示栈顶控制器。


                        ** 栈,先进后出(First-In/Last-Out)



                * UINavigationController(导航控制器)的其他属性、方法:


                    1. viewControllers childViewControllers都表示子控制器。(存放所有子控制器的""

                        ** childViewControllers属性是readonly, 不能直接@[]赋值。


                    2. UINavigationController(导航控制器)中增加控制器的若干方法:

                        * 调用 addChildViewController:方法(不会自动跳转)


                        * 调用 pushViewController:animated:方法


                        * 直接设置viewControllers = @[vc, vc1]; 属性


                        * 在创建导航控制器的同时, 通过initWithRootViewController直接指定"栈底"控制器。


                    3. topViewController获取当前栈顶的控制器。


                    4. 自己写代码实现回到上一个控制器, 回到第一个控制器。

                        * popViewControllerAnimated:方法, 移除栈顶的控制器。


                        * popToViweController:vc1 animated:YES 方法表示, 从栈顶不断的移除控制器,直到看到vc1控制器为止(回到指定的控制器)。


                        * popToRootViewControllerAnimated:YES 移除所有的控制器, 直到显示根控制器为止(回到栈底控制器)。



                * 设置导航栏的内容(导航栏高度44:

                    1. 一个导航控制器, 只有一个导航栏。pushpop只是更换导航控制器中的子控制器而已。导航栏始终使用的都是同一个


                    2. 导航栏中显示的内容, 取决于栈顶的控制器的navigationItem属性。

                        * 通过设置对应控制器的navigationItemtitle来改变标题。


                    3. 在每个控制器的viewDidLoad方法中设置当前控制器的navigationItem属性。


                    4. navigationItem属性的具体内容:

                        * title属性


                        * titleView属性


                        * leftBarButtonItem // 只能设置左上角的一个按钮


                        * leftBarButtonItems // 可以设置左上角有多个按钮


                        * rightBarButtonItem // 只能设置右上角的一个按钮


                        * rightBarButtonItems // 可以设置右上角有多个按钮


                        * backBarButtonItem // 设置下一个控制器, 左上角的按钮。默认情况下,该按钮文字与上一个控制器的title文字相同。



                    5. 通过storyboard创建导航控制器。


                    6. 通过调用导航控制器的navigationBar, 可以获取导航控制器的"导航栏"

                        * 在代理方法的DidBecomeActive事件中,输出导航栏的大小、位置

                            /** 参考代码:

                             UINavigationController *nav = self.window.rootViewController;

                            CGRect rect = nav.navigationBar.frame;

                             NSLog(@"%@",NSStringFromCGRect(rect));

                             

                             ** DidBecomeActive事件含义:程序获得焦点。与"程序进入前台"的区别: "进入前台", 然后才"获得焦点", 程序"获得焦点"意味着所有控件都可以开始监听事件了。

                             

                             "先进入前台  "获得焦点"

                             

                             "先失去焦点  "进入后台

                             */



               







            * UITabBarController























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值