美文网首页
主题一《基础常识》

主题一《基础常识》

作者: 东方奇迹 | 来源:发表于2020-07-04 23:49 被阅读0次

    01-项目中常见的文件(LaunchScreen)

    设置启动页面的方式:
    LaunchImage
    LaunchScreen.storyboard

    如果不设置启动界面,屏幕的尺寸大小是4/4s大小,size = {320,480}

    LaunchScreen.storyboard原理:
    在运行时,生成了一张对应尺寸的图片,来去设置启动界面。图片就在沙盒里面存放着!!!

    02-项目中常见的文件(info.plist)

    info.plist文件的作用:设置应用程序的配置信息

    info.plist常见key值:

    • Bundle name:app的名称
    • Bundle Identifer:应用程序唯一标识
    • Bundle version string,shot :版本号
    • Bundle version :打包的版本号

    03-项目中常见的文件(PCH)

    pch的配置:
    在Build Setting中搜索prefix
    Precompile Prefix Header 设置为YES
    Prefix Header设置$(SRCROOT)/xxx/xxx.pch
    (路径即:从工程根目录下/文件名/xxx.pch)

    pch的作用:
    1、存放公有宏
    2、存放公有头文件
    3、自定义log.

    #ifdef DEBUG
    
    #define YSLog(...) NSLog(__VA_ARGS__)
    
    #else
    
    #define YSLog(...)
    
    #endif
    
    

    pch的原理:
    把pch当中的所有内容给拷贝到工程当中每一个文件当中

    注意事项:如果有C文件,要做判断
    因为在每一个OC文件内部都隐式的有一个宏OBJC
    所以可以在pch文件最外层写上

    #ifdef __OBJC__
    #endif
    

    04-UIApplication单例

    1.UIApplication概念

    1) UIApplication对象是应用程序的象征
    2) 每一个应用都有自己的UIApplication对象,而且是单例的
    3) 一个iOS程序启动后创建的第一个对象就是UIApplication对象
    4) 通过[UIApplication sharedApplication]可以获得这个单例对象
    5) 利用UIApplication对象,能进行一些应用级别的操作

    2.UIApplication的常用属性

    1)设置应用程序图标右上角的红色提醒数字
    @property(nonatomic)NSInteger applicationIconBadgeNumber;

    2)设置物联网指示器的可见性
    @property(nonatomic,getter= isNetworkActivityIndicatorVisible)BOOL networkActivityIndicatorVisible;

    3)状态栏 (从iOS7开始,系统提供了2种管理状态栏的方式)

    (1)通过UIViewController管理(每一个UIViewController都可以拥有自己不同的状态栏)

    //配置Info.plist 不配置时系统默认是YES
    View controller-based status bar appearance = YES;
    a> 没有导航栏UINavigationController的ViewController,由ViewController自己管理自己
        // 状态栏的样式
        - (UIStatusBarStyle)preferredStatusBarStyle;
        // 状态栏的可见性
        - (BOOL)prefersStatusHidden;
        // 状态栏切换时的动画
        - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation ;
        // 可以使用viewController方法更新状态栏设置
        [self setNeedsStatusBarAppearanceUpdate];
    b> 有UINavigationController的ViewController,
        UINavigationController不会将preferredStatusBarStyle这个方法的调用转给它的子视图,而是有导航栏本身进行管理控制
        需要通过导航栏navigationBar的barStyle属性修改,
        // 状态栏文本颜色设置为白色
        self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
        // 状态栏文本颜色设置为黑市,默认就是黑色
        self.navigationController.navigationBar.barStyle = UIBarStyleDefault;
    c> 继承UINavigationController,比如LYNavigationController
         重写以下的方法,就可以将状态栏修改的权利下放给ViewController
          - (UIViewController *)childViewControllerForStatusBarStyle {
            return self.topViewController;
          }
          - (UIViewController *)childViewControllerForStatusBarHidden {
            return self.topViewController;
          }
    
        ViewController可以继续使用一下方法修改状态栏
         // 状态栏的样式
        - (UIStatusBarStyle)preferredStatusBarStyle;
        // 状态栏的可见性
        - (BOOL)prefersStatusHidden;
        // 可以使用viewController方法更新状态栏设置
        [self setNeedsStatusBarAppearanceUpdate];
    

    (2)通过UIApplication管理(一个应用程序的状态栏都是由它统一管理)

    //配置Info.plist 不配置时系统默认是YES (统一管理时必须配置)
    View controller-based status bar appearance = NO;
    在iOS9及之前使用:
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
    在iOS9之后使用:
    Status bar is initially hidden = NO;
    Status bar style = Light Content;
    

    4)openURL

    (1)iOS10之前
        [[UIApplication sharedApplication] openURL:url];
    (2)iOS10之后
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
        }];
    
      备注:作用
        (1) 打电话
        url = @"tel://10086";
        (2) 发短信
        url = @"sms://10086";
        (3) 发邮件
        url = @"mailto://1048811572@qq.com";
        (4) 打开网页
        url = @"https://www.baidu.com";
        (5) 打开其他的app
    

    05-UIApplication功能

    06-UIApplication代理

    iOS13之后苹果系统为了支持iPadOS的多窗口,推出了SceneDelegate类
    ###iOS13之前
    Appdelegate负责全权处理App生命周期和UI生命周期
    
    // 应用程序启动完毕时调用
    - (void)applicationDidFinishLaunching:(UIApplication *)application;
    // 应用程序已经获取焦点时调用(焦点:能否与用户进行交互)
    - (void)applicationDidBecomeActive:(UIApplication *)application;
    // 应用程序将要失去焦点时调用
    - (void)applicationWillResignActive:(UIApplication *)application;
    // 应用程序即将进入前台时调用
    - (void)applicationWillEnterForeground:(UIApplication *)application API_AVAILABLE(ios(4.0));
    // 应用程序已经进入后台时调用
    - (void)applicationDidEnterBackground:(UIApplication *)application API_AVAILABLE(ios(4.0));
    // 当应用程序收到内存警告时调用(程序员去清理缓存、图片、视频)
    - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application;
    // 当应用程序退出的时候调用
    - (void)applicationWillTerminate:(UIApplication *)application;
    
    ###iOS13之后
    Appdelegate负责处理
    * 处理App生命周期
    * 新的Scene Session 生命周期
    SceneDelegate负责处理
    *所有UI生命周期
    
    1923392-4aff6ec3cb30ae10.png 1923392-e3058e026bb56034.png

    07-应用程序的启动原理

    int main(int argc, char * argv[]) {
        NSString * appDelegateClassName;
        @autoreleasepool {
            // Setup code that might create autoreleased objects goes here.
            appDelegateClassName = NSStringFromClass([AppDelegate class]);
        }
        //第三个参数:UIApplication的名称或者是它子类的名称 nil = @"UIApplication"
        //第四个参数:UIApplication对象代理的名称
        //NSStringFromClass([AppDelegate class])
        return UIApplicationMain(argc, argv, nil, appDelegateClassName);
    }
    
    1、执行main函数
    2、执行UIApplicationMain
      2.1、 创建UIApplication对象,并设置UIApplication它的代理。
      2.2、 开启了一个事件循环(mainRunloop),主运行循环,死循环,保证应用程序不退出。
      2.3、 加载info.plist(判断info.list当中有没有指定Main,如果指定的话
        {
          系统自动帮你做的事情:
          加载Main.storyBoard,加载之前会创建一个window,
          因为每一个window都必须得要设置一个根控制器.rootViewController,设置的目的是强引用根控制器让它不释放,
          所以会把Main.storyBoard当中箭头指向的控制器设置为window的rootViewController。
          把Main.storyBoard当中箭头指向的控制器的view添加到window,让window显示出来。
        }
    
      2.4、 通知应用程序代理,应用程序启动完毕. didFinishLaunchingWithOptions:
    

    08-UIWindow

    • UIWindow是一种特殊的UIView ,通常 在一个app中至少有一个UIWindow;
    • i0S程序启动完毕后,创建的第一个视图控件就是UIWindow. 接着创建控制器 的view,最后将控制器的view添加到UIWindow上,于是控制器的view就显示在屏暮上了;
    • 一个i0S程序之所以能显示到屏幕上,完全是因为它有UIWindow;
    • 也就说,没有UIWindow,就看不见任何UI界面。
    ### iOS13之前
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // 1.创建窗口
        self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
        // 2.设置窗口的根控制器(每一个window都必须得要设置一个根控制器.rootViewController)
        UIViewController *vc = [UIViewController new];
        self.window.rootViewController = vc;
        // 3.显示窗口
        [self.window makeKeyAndVisible];
    
        ## iOS9之后,如果添加了多个窗口,控制器它会自动把状态栏给隐藏掉
        // 解决办法:把状态栏给应用程序管理
        // 将View controller-based status bar appearance 设置成NO
        self.window1 = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
        // 2.设置窗口的根控制器
        UIViewController *mvc = [UIViewController new];
        self.window1.rootViewController = mvc;
        // 3.显示窗口
        [self.window1 makeKeyAndVisible];
        /**
            makeKeyAndVisible:
            1.设置当前窗口为应用程序的主窗
             [UIApplication sharedApplication] . keyWindow = self.window;
            2.显示窗口
            self .window. hidden = NO;
            把窗口的根控制器添加到窗口上面。
            [self.window addSubview:self.window.rootViewController.view];
        */
    
        ## 设置窗口层级
        //  级别等级:UIWindowLevelStatusBar > UIWindowLevelAlert > UIWindowLevelNormal
        self.window1.windowLevel = UIWindowLevelStatusBar;
    
       ## alertView 、 键盘、状态栏其实都是window
      
        return YES;
    }
    
    • keyWindow
      This property holds the UIWindow object in the windows array that is most recently sent the makeKeyAndVisible message.
      意思就是最近一次发送 makeKeyAndVisible message的window。
    • makeKeyAndVisible
      This is a convenience method to show the current window and position it in front of all other windows at the same level or lower. If you only want to show the window, change its hidden property to NO.
      意思就是用这个方法可以方便的将当前window放在所有window的最顶层(当然是相同level或者跟level更低的比较)。
    • 找window方法
    a、首先获取应用程序对象,调用应用程序对象的属性获取window
    /**
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"welcome" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
        [alertView show];
        UIView *testView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 50, 50)];
        testView.backgroundColor = [UIColor yellowColor];
        [window addSubview:testView];
         Tips: 应用程序的keyWindow 有时(alertView弹出时)并不是我们想要的window
    */
    b、首先获得应用程序对象 获取应用程序代理对象即入口类对象 获取入口类对象的属性
    
    UIApplication *application = [UIApplication sharedApplication];
    
    ZYAppDelegate *appDelegate = application.delegate;
    
    UIWindow *window2 = appDelegate.window;
    
    Tips:代码耦合度较高
    
    c、首先获得应用程序对象  获取应用程序对象的所有window 属性windows 然后取出第一个 索引为0
    
    UIWindow *window3 = [application.windows objectAtIndex:0];
    
    Tips:Perfect
    

    09-从StoryBoard加载控制器

    - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
        UIWindowScene *windowScene = (UIWindowScene *)scene;
        self.window = [[UIWindow alloc] initWithWindowScene:windowScene];
        self.window.frame = windowScene.coordinateSpace.bounds;
        self.window.backgroundColor = [UIColor grayColor];
        
        // 通过storyBoard加载控制器
        // 1、创建storyBoard对象(比如加载Main.storyBoard对象)
        UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
        // 2、加载storyBoard箭头指向的控制器
        UIViewController *vc = [storyBoard instantiateInitialViewController];
        // 可以加载storyBoard中指定的控制,通过storyBoardID
        UIViewController *other = [storyBoard instantiateViewControllerWithIdentifier:@"otherStoryBoard"];
        
        self.window.rootViewController = vc;
        [self.window makeKeyAndVisible];
    }
    
    
    #备注
    如果初始不需要使用Main.storyBoard,或者是说使用自己其他指定的控制器,请将info.plist文件中的以下值设置为空
    Main storyboard file base name = 空值
    好处:可以避免应用程序启动的时候默认加载一个Main.storyBoard文件创建一个不需要用的控制器,可以节省内存
    
    1923392-a2fe3987d28c5788.png 1923392-cb30ae60a52e6f8b.png

    10-通过xib加载控制器的view

    - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
        UIWindowScene *windowScene = (UIWindowScene *)scene;
        self.window = [[UIWindow alloc] initWithWindowScene:windowScene];
        self.window.frame = windowScene.coordinateSpace.bounds;
        self.window.backgroundColor = [UIColor grayColor];
        
        // 通过Xib加载控制器的view
        // 1、创建Xib文件
        // 2、告诉Xib描述哪一个控制器的view,->绑定类
        // 3、告诉控制器,Xib当中哪一个view去描述控制器的view,->连线
    
        
        /**
        initWithNibName:
        1、指定名称,会加载指定名称的xib;
        2、如果name指定为nil
        先去加载有没有相同名称的xib,如果有就去加载(SeconderViewController.xib)
        如果没有相同名称,还会去找相同名称去掉Controller(SeconderView.xib)
        3、如果还没有,就不用xib来描述控制器的view,去创建一个空白view
        */
    
        //SeconderViewController  *vc = [[SeconderViewController alloc]initWithNibName:nil bundle:nil];
    
        //init方法默认会调用initWithNibName:
        SeconderViewController  *vc = [[SeconderViewController alloc]init];
    
        self.window.rootViewController = vc;
        [self.window makeKeyAndVisible];
    }
    
    
    1923392-5048b5b371bb948c.gif 1923392-8d6b32b16b0027dd.png

    11-LoadView

      // - (UIView *)view {
      //  if (_view == nil) {
      //      [self loadView];
      //      [self viewDidLoad];
      //  }
      //  return _view;
      // }
    
    loadView 是 viewController中View的生命周期其中一环
    loadView 作用:用来创建控制器的View
    什么时候调用:当控制器的View,第一次使用的时候调用
    loadView的底层原理:
    1、先判断当前控制器是不是从storeBoard加载的控制器,如果是从storyBoard加载的控制器,那么它就会从storyBoard当中加载的控制器的View,设置当前控制器的view
    2、当前控制器是不是从xib当中加载的,如果是从xib当中加载的话,把xib当中指定的View,设置为当前控制的view
    3、如果也不是从xib加载的,它会创建一个空白的View
    
    // 一旦重写了loadView的方法,就说明要自己定义View ,即使写了[super loadView]也不行
    # 使用场景:当前控制器的View一显示时,就 是一张图片,或者UIWebView
    # 好处:可以节省内存,少创建一个空白的View
    - (void)loadView {
      // 特别注意的一定,比如下面的写法会造成死循环
      // 原因:
      // self.view.bounds是调用了self.view的getter方法,而self.view的getter方法底层写法类似以下
      
      // self.view = [[UIView alloc]initWithFrame:self.view.bounds];
      
      #正确写法
      self.view = [[UIView alloc]initWithFrame:[UIScreen mainScreen].bounds];
    
      #如果想self.view是一张图片,写法如下
      UIImageView *imgView = [[UIImageView alloc]initWithImage:@"test.jpg"];
      self.view = imgView;
    }
    
    - (void)viewDidLoad {
      [super viewDidLoad];
    
    }
    

    相关文章

      网友评论

          本文标题:主题一《基础常识》

          本文链接:https://www.haomeiwen.com/subject/cuyuqktx.html