UIWindow

  • 程序启动完成时加载窗口
// 程序启动完成的时候
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // 1.创建窗口,注意窗口必须要有尺寸,尺寸跟屏幕一样大的尺寸,窗口不要被释放
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor redColor];

    // 2.创建窗口的根控制器
    UIViewController *vc = [[UIViewController alloc] init];
    vc.view.backgroundColor = [UIColor yellowColor];

    [vc.view addSubview:[UIButton buttonWithType:UIButtonTypeContactAdd]];

    // 如果设置窗口的根控制器,默认就会把控制器的view添加到窗口上
    // 设置窗口的根控制器,默认就有旋转功能
    self.window.rootViewController = vc;

//    [self.window addSubview:vc.view];

    // 3.显示窗口
    [self.window makeKeyAndVisible];

    return YES;
}
  • 窗口有层级关系
    • UIWindowLevelNormal < UIWindowLevelStatusBar < UIWindowLevelAlert
// 设置窗口的层级关系
    self.window1.windowLevel = UIWindowLevelStatusBar;
  • 键盘也是窗口,状态栏也是
 // 判断下键盘是不是窗口
//    NSLog(@"%@",application.windows);
    // 如何才能弹出键盘
    // 如果需要看到键盘,必须要把textField添加到一个View上面
    UITextField *textField = [[UITextField alloc] init];
    _textField = textField;// 必须强引用
    [textField becomeFirstResponder];// 打开键盘
    [self.window addSubview:textField];

//    NSLog(@"%@",application.windows);

    // 显示窗口
    [self.window makeKeyAndVisible];

-

    // application.windows:只要一给delegate的window属性赋值,就会添加到windows数组。
//    NSLog(@"%@",application.windows);

    // 2.显示窗口
    // makeKeyAndVisible:成为app的主窗口并且显示
    [self.window makeKeyAndVisible];
//    NSLog(@"%@",application.windows);
    //    self.window.hidden = NO;
    NSLog(@"%@",self.window);
  • 通过storyboard创建控制器
    • 1、加载storyboard
    • 2、实例化控制器
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    // 创建窗口
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

    // 创建窗口的跟控制器
    // 加载storyboard
    // storyboard文件名,不需要带后缀
    // nil:  [NSBundle mainBundle]
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    // 通过storyboard创建控制器
    // instantiateInitialViewController:加载箭头指向的控制器
//    UIViewController *vc = [storyboard instantiateInitialViewController];

// 根据storyboard的中控制器的标示加载
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"green"];

    NSLog(@"%@",[vc class]);
    self.window.rootViewController = vc;

    // 显示窗口
    [self.window makeKeyAndVisible];
    return YES;
}
  • 通过xib创建控制器
    • 一定要描述xib的文件拥有者是控制器,也就是说这个xib是用来描述控制器
     // 通过xib创建控制器
    ViewController *vc = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];

loadView方法

  • loadView作用:自定义控制器的view

    • loadView什么时候调用:第一次使用控制器的view的时候调用

    • 注意:在这个方法中如果没有自定义view,就不能获取控制器的view

    • 一旦重写了这个方法,就不要调用[super loadView]

    • 如果重写了这个方法,就不会去加载storyboard描述的控制器的View

- (void)loadView
{
    // 创建控制器view
    self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    // 这里设置颜色不靠谱,因为最终会返回到程序启动完成时
    self.view.backgroundColor = [UIColor purpleColor];
}
  • 系统内部的实现原理
- (UIView *)view
{
    if (_view == nil) {
        [self loadView];
        [self viewDidLoad];
    }
    // 最终会将view返回到外界,属性应由外面设置
    return _view;
}
  • 错误写法
#pragma mark - 直接不实现就是系统默认的做法
- (void)loadView
{
    // super ->  UIViewController
    // 系统默认的做法,一定不要这样写
    [super loadView];
}

  • 通过xib创建控制器的view

    • 默认loadView可以加载storyboard和xib描述的控制器的view
    // 加载跟类名相同的xib
    // 如果描述控制器View的xib跟控制器的类名相同,就会去加载
    // 只有控制器的init方法底层会调用initWithNibName:bundle:

    // 只要通过initWithNibName:bundle:初始化控制器,并且nibName为nil,就会执行以下几步。
    // XMGViewController类型
    // 1.寻找有没有跟控制器类名同名但是不带Controller的xib,如果有就会去加载(XMGView.xib)
    // 2.寻找有没有跟控制器类名同名的xib,如果有就会去加载(XMGViewController.xib)
    // 3.如果都没有找到,创建空的view,
    UIViewController *vc = [[ViewController alloc] initWithNibName:@"VC" bundle:nil];

    self.window.rootViewController = vc;
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{

    NSLog(@"%s",__func__);

    return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
}
  • 创建UIViewController控制器,控制器的view并没有创建

    • 控制器的view懒加载:第一次使用的时候才会去加载,并不是创建UIViewController控制器的时候去加载
    • 可以用isViewLoaded方法判断一个UIViewController的view是否已经被加载

    • 控制器的view加载完毕就会调用viewDidLoad方法

  UIViewController *vc = [[ViewController alloc] init];
  // 只有用到时才会加载
    vc.view.backgroundColor = [UIColor redColor]
  • 默认控制器的view:几乎透明
    • 可以显示后面的控件并使用 alpha > 0
  • 如果控制器是窗口的根控制器就可以不用设置尺寸
    • 默认就是窗口的尺寸
- (void)loadView
{
    self.view = [[UIView alloc] initWithFrame:CGRectZero];

    self.view.backgroundColor = [UIColor yellowColor];
}
  • 在viewDidLoad中打印控制器的尺寸不准确,通常在viewDidAppear
#pragma mark - view完全显示的时候调用
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    NSLog(@"%@",NSStringFromCGRect(self.view.bounds));

}

> 1.控制器view的创建(空项目) 2.研究控制器view的加载,首先需要自定义控制器view,作为根控制器。 3.证明控制器的view是透明的:直接通过alloc,init创建的控制器的view默认是透明的 4.通过storyboard加载的控制器view,和storyboard描述的一样。 5.重写控制器的loadView,不会去加载storyboard. 6.解释loadView方法 1> loadView作用:一般用来创建自定义的view 2> loadView什么时候调用:当控制器的view没有创建的时候,就会调用loadView 去创建控制器的view. 3> loadView使用注意:如果重写loadView里面没有创建控制器的view,就不能使 用self.view,会造成死循环。 7.通过xib加载控制器的view 1> 取一个CZViewController123的xib描述控制器的view,通过这个xib加载控制器的 view 2> 取一个CZViewController的xib描述控制器的view,通过这个xib加载控制器的 view,不用告诉控制器去加载哪个xib,会自动去加载CZViewController这个xib。 3> 取一个CZView的xib描述控制器的view,通过这个xib加载控制器的view,不用告 诉控制器去加载哪个xib,优先去加载CZView这个xib。 8.PPT演示LoadView的默认做法。 8.1> 控制器View的决定权:重写LoadView>storyboard>nibName>xib 9.控制器的view是延迟加载的。 9.1> 验证控制器的view延迟加载,只有在窗口显示的时候,才会调用loadView 方法。 9.2> 用到控制器view的时候才会加载控制器的view,设置控制器view的背景颜色 9.3> 通过设置控制器view的颜色,引出两个疑问。 1> 重写loadView,不是不会加载xib了吗,控制器的view由loadView决定, loadView显示什么颜色,就是什么颜色。 2> loadView只是创建控制器View,并不能决定控制器的view的颜色。 3> 理解loadView的调用时刻:第一次调用self.view,底层会调用LoadView 方法,创建控制器的view,这时候的view是LoadView的颜色,但是 vc.view.backgroundColor,是拿到控制器的view又设置一次颜色,把 LoadView设置的颜色给覆盖了。 4> 在viewDidLoad也设置颜色,还是vc.view.backgroundColor决定,因为 vc.view就是获取控制器的view,只有控制器的view加载完成之后,才能获取 到,因此先调用viewDidLoad。 10.如何快速生成一个xib描述控制器的view,之前还要在xib拖视图,设置xib描述哪个 控制器,很麻烦。 1> 定义新的控制器的时候,勾选xib,会自动搞一个xib描述控制器的view. 2> 会自动生成一个和控制器同名的xib,并且里面设置好了。 学习方法:学习原理,不要一开始就用最快的方式创建xib,开发的时候才使用最快的方 式。

results matching ""

    No results matching ""