zoukankan      html  css  js  c++  java
  • UIApplication,UIWindow,UIViewController,UIView(layer)

    转载自:http://www.cnblogs.com/iCocos/p/4684749.html

    UIApplication,UIWindow,UIViewController,UIView(layer)简单介绍

    一:UIApplication:单例(关于单例后面的文章中会详细介绍,你现在只要知道,单例在应用程序的整个生命周期中只有一个对象)。

    App的启动过程

    打开程序之后-》

    • 1:Main函数
    • 2:UIapplicationMain函数
    • 3:初始化UIApplication(创建)
    • 4:设置UIApplication代理和相应的代理属性
    • 5:开启事件循环,监听系统事件
    • 6监测info。plist文件,看看是否有Main.StoryBoard文件存在

    有:/*****************************************华丽的分割线******************************************/

    • 1:加载Main.StoryBoard
    • 2:在StoryBoard上面创建一个UIwindow,
    • 3:设置Window的根控制器
    • 4:遍历控制器上面的所有子控件,没有则创建对应的控件

    没有:/*****************************************华丽的分割线******************************************/

    • 1:通过一个强引用创建UIWindow
    •     self.window = [[UIWindow alloc] init];
    • 2:设置Window的frame为屏幕的bounds
    •     self.window.frame = [UIScreen mainScreen].bounds;
    • 3:设置window的根控制器
    •     self.window.rootViewController = [[UIViewController alloc] init];
    • 4:将window作为主窗口并且显示到界面上
    •     [self.window makeKeyAndVisible];

    这里有一个非常重要但是很少有人去留意的地方,也是作为一个iOS程序员必须知道的,那就是Main函数,我们知道Main函数是一个程序的入口,那么在iOS开发中Main函数有哪些需要注意的地方呢:

    • int UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);

    argc、argv:直接传递给UIApplicationMain进行相关处理即可

    principalClassName:指定应用程序类名(app的象征),该类必须是UIApplication(或子类)。如果为nil,则用UIApplication类作为默认值

    delegateClassName:指定应用程序的代理类,该类必须遵守UIApplicationDelegate协议

    方法:

    复制代码
     1 // app启动完成的时候调用
     2 
     3 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     4 
     5  
     6 
     7     NSLog(@"%s",__func__);
     8 
     9     
    10 
    11     return YES;
    12 
    13 }
    14 
    15  
    16 
    17 // app即将失去焦点的时候调用
    18 
    19 - (void)applicationWillResignActive:(UIApplication *)application {
    20 
    21     NSLog(@"%s",__func__);
    22 
    23 }
    24 
    25  
    26 
    27 // app进入后台
    28 
    29 - (void)applicationDidEnterBackground:(UIApplication *)application {
    30 
    31    NSLog(@"%s",__func__);
    32 
    33     // 保存一些数据
    34 
    35     
    36 
    37 }
    38 
    39  
    40 
    41 // app即将进入前台的时候调用
    42 
    43 - (void)applicationWillEnterForeground:(UIApplication *)application {
    44 
    45     NSLog(@"%s",__func__);
    46 
    47 }
    48 
    49  
    50 
    51 // app即将获取焦点的时候
    52 
    53 // 当应用程序获取焦点的时候才能够与用户交互
    54 
    55 - (void)applicationDidBecomeActive:(UIApplication *)application {
    56 
    57     NSLog(@"%s",__func__);
    58 
    59 }
    60 
    61  
    62 
    63 // app关闭的时候调用
    64 
    65 - (void)applicationWillTerminate:(UIApplication *)application {
    66 
    67     
    68 
    69 }
    70 
    71  
    72 
    73 // 监听内存警告
    74 
    75 - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
    76 
    77 {
    78 
    79     NSLog(@"内存警告");
    80 
    81     // 清楚图片缓存
    82 
    83 }
    84 
    85  
    复制代码

    UIApplication单例对象常用功能:

        // 获取应用程序的象征

       UIApplication *app =  [UIApplication sharedApplication];

        

        // 应用程序图片的提醒数字:(这里需要注册)

    复制代码
     1     app.applicationIconBadgeNumber = 100;
     2 
     3     
     4 
     5     // 创建通知对象
     6 
     7     UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
     8 
     9     
    10 
    11     
    12 
    13     // 注册用户通知
    14 
    15     [app registerUserNotificationSettings:settings];
    复制代码

        

        // 联网状态 1 app.networkActivityIndicatorVisible = YES; 

        

        // 设置状态栏

     1 app.statusBarHidden = NO; 2 3 app.statusBarStyle = UIStatusBarStyleLightContent; 

        

        

        - (BOOL)openURL:(NSURL*)url;

        

        openURL:方法的部分功能有

    复制代码
     1     打电话
     2 
     3     UIApplication *app = [UIApplication sharedApplication];
     4 
     5     [app openURL:[NSURL URLWithString:@"tel://10086"]];
     6 
     7     
     8 
     9     发短信
    10 
    11     [app openURL:[NSURL URLWithString:@"sms://10086"]];
    12 
    13     
    14 
    15     发邮件
    16 
    17     [app openURL:[NSURL URLWithString:@"mailto://12345@qq.com"]];
    18 
    19     
    20 
    21     打开一个网页资源
    22 
    23     [app openURL:[NSURL URLWithString:@"http://ios.itcast.cn"]];
    24 
    25  
    复制代码

    二:UIWIndow

    UIWindow是一种特殊的UIView,通常在一个app中至少会有一个UIWindow

    iOS程序启动完毕后,创建的第一个视图控件就是UIWindow,接着创建控制器的view,最后将控制器的view添加到UIWindow上,于是控制器的view就显示在屏幕上了

    一个iOS程序之所以能显示到屏幕上,完全是因为它有UIWindow

    也就说,没有UIWindow,就看不见任何UI界面

    添加UIView到UIWindow中两种常见方式:

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

    直接将view添加到UIWindow中,但并不会理会view对应的UIViewController

    • @property(nonatomic,retain) UIViewController *rootViewController;

    自动将rootViewController的view添加到UIWindow中,负责管理rootViewController的生命周期

    常用方法

    • - (void)makeKeyWindow;

    让当前UIWindow变成keyWindow(主窗口)

    • - (void)makeKeyAndVisible; 

    让当前UIWindow变成keyWindow,并显示出来

    [UIApplication sharedApplication].windows

    在本应用中打开的UIWindow列表,这样就可以接触应用中的任何一个UIView对象

    (平时输入文字弹出的键盘,就处在一个新的UIWindow中)

    [UIApplication sharedApplication].keyWindow

    用来接收键盘以及非触摸类的消息事件的UIWindow,而且程序中每个时刻只能有一个UIWindow是keyWindow。如果某个UIWindow内部的文本框不能输入文字,可能是因为这个UIWindow不是keyWindow

    view.window

    获得某个UIView所在的UIWindow

    UIWindow还有一个属性需要注意的,虽然我吗平时很少用到:

    • @property(nonatomic) UIWindowLevel windowLevel;   

    对应de属性值:

    1. UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal;
    2. UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert;
    3. UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatusBar;

    三:UIViewController

    控制器的创建 

    • 了解UIStoryboard对象,通过这个对象,就能加载storyboard文件 注意:必须要有storyboard,创建UIStoryboard对象才有意义,alloc init创 建UIStoryboard对象没有意义
    1.1> instantiateInitialViewController:默认加载箭头指向的控制器 

    1.2> instantiateViewControllerWithIdentifier:根据标识在storyboard查找 控制器,并且创建。 

    ○ 标识不能乱传,会报错的,必须storyboard有这个标识才行

    通过xib创建控制器的view(空项目) • 首先得要有xib。 

    1 xib注意点:(演示没有的后果)
    1> xib里面必须有一个view描述控制器的view,因为控制器的view 属性必须有值。
    2> xib需要指定描述哪一个控制器,描述UIView不需要,因为xib里 面可以描述很多UIView,不能固定死,但是控制器就不一样了,一个 xib就用来描述一个控制器。
     xib里面可能有很多view,需要拖线指明哪个是控制器的view 

    2 xib和storyboard的区别 storyboard已经指定了控制器的view,不需要我们管,xib需要我们 手动管理。 

    UIViewController启动过程

    // 系统默认的做法:如果指定了storyboard或者xib,就会加载他们描述的控制器的view

    复制代码
     1 - (void)loadView
     2 
     3 {
     4 
     5    
     6 
     7 }
     8 
     9  
    10 
    11 - (UIView *)view
    12 
    13 {
    14 
    15     if (_view == nil) {
    16 
    17         [self loadView];
    18 
    19         [self viewDidLoad];
    20 
    21     }
    22 
    23     return _view;
    24 
    25 }
    复制代码

    总之LoadView是我们自定义View的时候调用的,苹果提供这个方法的目的也就是这个,所以我们以后自定义View的时候不要在ViewDidLoad里面实现,因为ViewDidLoad的意思是View加载完毕以后调用,那么这个时候已经有一个View了,我们再去创建一个View,虽然可以,但是这不是浪费内存吗。

    复制代码
     1     // 1.创建窗口
     2 
     3     self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
     4 
     5     
     6 
     7     // 设置窗口的颜色
     8 
     9     self.window.backgroundColor = [UIColor purpleColor];
    10 
    11     
    12 
    13     // 2.创建根控制器,在设置窗口的根控制器
    14 
    15     UIViewController *vc = [[UIViewController alloc] init];
    16 
    17     
    18 
    19     // 设置窗口的根控制器,底层会自动把根控制器的view添加到窗口上,并且让控制器的view有旋转功能
    20 
    21     self.window.rootViewController = vc;
    22 
    23     
    24 
    25     // 3.显示窗口
    26 
    27     // makeKeyAndVisible:让窗口成为应用程序的主窗口,并且显示窗口
    28 
    29     [self.window makeKeyAndVisible];
    30 
    31     
    32 
    33     return YES;
    34 
    35  
    复制代码

    生命周期:

    四:UIView(Layer)

     控制器的view的创建 

    1> loadView作用:一般用来创建自定义的view 

    2> loadView什么时候调用:当控制器的view没有创建的时候,就会调用loadView 去创建控制器的view. 

    3> loadView使用注意:如果重写loadView里面没有创建控制器的view,就不能使 用self.view,会造成死循环。 

    注意:

    重写loadView,不是不会加载xib了吗,控制器的view由loadView决定, loadView显示什么颜色,就是什么颜色。
    loadView只是创建控制器View,并不能决定控制器的view的颜色。
    理解loadView的调用时刻:第一次调用self.view,底层会调用LoadView 方法,创建控制器的view,这时候的view是LoadView的颜色,但是 

    vc.view.backgroundColor,是拿到控制器的view又设置一次颜色,把 LoadView设置的颜色给覆盖了。
    在viewDidLoad也设置颜色,还是vc.view.backgroundColor决定,因为 

    vc.view view, view 

    loadView只是创建控制器View,并不能决定控制器的view的颜色。 

    vc.view.backgroundColor,是拿到控制器的view又设置一次颜色,把 LoadView设置的颜色给覆盖了。
     在viewDidLoad也设置颜色,还是vc.view.backgroundColor决定,因为 vc.view就是获取控制器的view,只有控制器的view加载完成之后,才能获取 到,因此先调用viewDidLoad。

    理解loadView的调用时刻:第一次调用self.view,底层会调用LoadView 方法,创建控制器的view,这时候的view是LoadView的颜色,但是

    还有一个概念值得注意的,那就是Layer那么Layer事什么东西呢,他有什么用?他喝UIView又是什么关系?

    UIView中属性与方法的详细解释:

    • @interface UIView : UIResponder<NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem>
    复制代码
      1 /**
      2 
      3  *  通过一个frame来初始化一个UI控件
      4 
      5  */
      6 
      7 - (id)initWithFrame:(CGRect)frame;
      8 
      9  
     10 
     11 // YES:能够跟用户进行交互
     12 
     13 @property(nonatomic,getter=isUserInteractionEnabled) BOOL userInteractionEnabled;  // default is YES
     14 
     15  
     16 
     17 // 控件的一个标记(父控件可以通过tag找到对应的子控件)
     18 
     19 @property(nonatomic)                                 NSInteger tag;                // default is 0
     20 
     21  
     22 
     23 // 图层(可以用来设置圆角效果阴影效果)
     24 
     25 @property(nonatomic,readonly,retain)                 CALayer  *layer;
     26 
     27  
     28 
     29 @end
     30 
     31  
     32 
     33 @interface UIView(UIViewGeometry)
     34 
     35 // 位置和尺寸(以父控件的左上角为坐标原点(0, 0))
     36 
     37 @property(nonatomic) CGRect            frame;
     38 
     39  
     40 
     41 // 位置和尺寸(以自己的左上角为坐标原点(0, 0))
     42 
     43 @property(nonatomic) CGRect            bounds;
     44 
     45  
     46 
     47 // 中点(以父控件的左上角为坐标原点(0, 0))
     48 
     49 @property(nonatomic) CGPoint           center;      
     50 
     51  
     52 
     53 // 形变属性(平移缩放旋转)
     54 
     55 @property(nonatomic) CGAffineTransform transform;   // default is CGAffineTransformIdentity
     56 
     57  
     58 
     59 // YES:支持多点触摸
     60 
     61 @property(nonatomic,getter=isMultipleTouchEnabled) BOOL multipleTouchEnabled;   // default is NO
     62 
     63 @end
     64 
     65  
     66 
     67 @interface UIView(UIViewHierarchy)
     68 
     69 // 父控件
     70 
     71 @property(nonatomic,readonly) UIView       *superview;
     72 
     73  
     74 
     75 // 子控件(新添加的控件默认都在subviews数组的后面, 新添加的控件默认都显示在最上面最顶部)
     76 
     77 @property(nonatomic,readonly,copy) NSArray *subviews;
     78 
     79  
     80 
     81 // 获得当前控件所在的window
     82 
     83 @property(nonatomic,readonly) UIWindow     *window;
     84 
     85  
     86 
     87 // 从父控件中移除一个控件
     88 
     89 - (void)removeFromSuperview;
     90 
     91  
     92 
     93 // 添加一个子控件(可以将子控件插入到subviews数组中index这个位置)
     94 
     95 - (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;
     96 
     97  
     98 
     99 // 交换subviews数组中所存放子控件的位置
    100 
    101 - (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2;
    102 
    103  
    104 
    105 // 添加一个子控件(新添加的控件默认都在subviews数组的后面, 新添加的控件默认都显示在最上面最顶部)
    106 
    107 - (void)addSubview:(UIView *)view;
    108 
    109  
    110 
    111 // 添加一个子控件view(被挡在siblingSubview的下面)
    112 
    113 - (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;
    114 
    115  
    116 
    117 // 添加一个子控件view(盖在siblingSubview的上面)
    118 
    119 - (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;
    120 
    121  
    122 
    123 // 将某个子控件拉到最上面(最顶部)来显示
    124 
    125 - (void)bringSubviewToFront:(UIView *)view;
    126 
    127  
    128 
    129 // 将某个子控件拉到最下面(最底部)来显示
    130 
    131 - (void)sendSubviewToBack:(UIView *)view;
    132 
    133  
    134 
    135 /**系统自动调用(留给子类去实现)**/
    136 
    137 - (void)didAddSubview:(UIView *)subview;
    138 
    139 - (void)willRemoveSubview:(UIView *)subview;
    140 
    141  
    142 
    143 - (void)willMoveToSuperview:(UIView *)newSuperview;
    144 
    145 - (void)didMoveToSuperview;
    146 
    147 - (void)willMoveToWindow:(UIWindow *)newWindow;
    148 
    149 - (void)didMoveToWindow;
    150 
    151 /**系统自动调用**/
    152 
    153  
    154 
    155 // 是不是view的子控件或者子控件的子控件(是否为view的后代)
    156 
    157 - (BOOL)isDescendantOfView:(UIView *)view;  // returns YES for self.
    158 
    159  
    160 
    161 // 通过tag获得对应的子控件(也可以或者子控件的子控件)
    162 
    163 - (UIView *)viewWithTag:(NSInteger)tag;     // recursive search. includes self
    164 
    165  
    166 
    167 /**系统自动调用(留给子类去实现)**/
    168 
    169 // 控件的frame发生改变的时候就会调用,一般在这里重写布局子控件的位置和尺寸
    170 
    171 // 重写了这个写方法后,一定调用[super layoutSubviews];
    172 
    173 - (void)layoutSubviews;
    174 
    175  
    176 
    177 @end
    178 
    179  
    180 
    181 @interface UIView(UIViewRendering)
    182 
    183 // YES : 超出控件边框范围的内容都剪掉
    184 
    185 @property(nonatomic)                 BOOL              clipsToBounds;
    186 
    187  
    188 
    189 // 背景色
    190 
    191 @property(nonatomic,copy)            UIColor          *backgroundColor; // default is nil
    192 
    193  
    194 
    195 // 透明度(0.0~1.0)
    196 
    197 @property(nonatomic)                 CGFloat           alpha;                      // default is 1.0
    198 
    199  
    200 
    201 // YES:不透明  NO:透明
    202 
    203 @property(nonatomic,getter=isOpaque) BOOL              opaque;                     // default is YES
    204 
    205  
    206 
    207 // YES : 隐藏  NO : 显示
    208 
    209 @property(nonatomic,getter=isHidden) BOOL              hidden;
    210 
    211  
    212 
    213 // 内容模式
    214 
    215 @property(nonatomic)                 UIViewContentMode contentMode;                // default is UIViewContentModeScaleToFill
    216 
    217 @end
    218 
    219  
    220 
    221  
    复制代码

    /******************************************************************************

     *                                                                            *

     *                        UIView分类-Block动画方法                            *

     *                                                                            *

     *                            iCocos--Description                             *

     *                                                                            *

     ******************************************************************************/

    复制代码
     1 @interface UIView(UIViewAnimationWithBlocks)
     2 
     3 + (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;
     4 
     5 + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;
     6 
     7  
     8 
     9 + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations;
    10 
    11 + (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;
    12 
    13 @end
    14 
    15  
    16 
    17  
    复制代码

    五:UIApplication,UIWindow,UIViewController,UIView(layer)

    本博文由博主(iCocos)独立编写或者借鉴别人的好文章进行修改而成,如果不对的地方望指正,谢谢! 如果您还有看到新浪博客关于IOS梦工厂的博文,麻烦请到这里找更完整更清晰的版本,博主已从http://blog.sina.com.cn/s/articlelist_3288975567_0_1.html转移到博客园
  • 相关阅读:
    局域网内的邮件收发
    小菜鸟入门nginx
    记一次结巴分词.net core 2.0版 nuget发布过程
    记一次 .net core publish 之后找不到视图文件的问题
    eShopOnContainer 第一步
    Ocelot网关统一查看多个微服务asp.net core项目的swagger API接口
    在Azure中创建asp.net core 应用
    微服务监控zipkin、skywalking以及日志ELK监控系列
    微服务监控zipkin+asp.net core
    Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列之部署master/node节点组件(四)
  • 原文地址:https://www.cnblogs.com/Jenaral/p/5030991.html
Copyright © 2011-2022 走看看