您的位置:首页 > 产品设计 > UI/UE

UIWindow详解

2015-11-26 14:35 363 查看
UIScreen(屏幕),UIWindow(窗口),UIView(视图)是iOS的几个基本界面元素。其中UIWindow(窗口)和UIView(视图)是为iPhone应用程序构造用户界面的可视组件。UIWindow为内容显示提供背景平台,UIView负责绝大部分的内容描画,并负责响应用户的交互。

### 1.UIScreen一般也只是用来获取屏幕大小

```
CGRect screenBounds = [[UIScreen mainScreen] bounds];
//返回的是带有状态栏的Rect (0.0,0.0,320.0,480.0)

CGRect viewBounds = [[UIScreen mainScreen] applicationFrame];
//不包含状态栏的Rect(0.0,20.0,320.0,480.0)[iphone状态栏高度20像素]
```

### 2.视图是UIView类的实例,负责在屏幕上定义一个矩形区域。

视图在展示用户界面及响应用户界面交互方面发挥关键作用。每个视图对象都要负责渲染视图矩形区域中的内容,并响应该区域中发生的操作事件。视图是应用程序与用户交互的重要机制。

在iOS中视图和视图控制器紧密协作,视图控制器的作用是处理视图的装载与卸载、处理由于设备旋转导致的界面旋转,以及和用于构建复杂用户界面的高级导航对象进行交互。

### 3.下面重点谈谈UIWindow

UIWindow对象是所有UIView的根,管理和协调的应用程序的显示。一般应用程序只有一个UIWindow对象,即使有多个UIWindow对象,也只有一个UIWindow可以接受到用户的触屏事件。

在Mac OS X中,NSWindow的父类是NSResponder;而在iPhone OS中,UIWindow的父类是UIView。因此,UIWindow窗口在iOS中也是一个视图对象。

在创建应用程序窗口时,应该总是将其初始的边框尺寸设置为整个屏幕的大小。如果您的窗口是从 nib文件装载得到,Interface Builder并不允许创建比屏幕尺寸小的窗口;然而,如果您的窗口是通过编程方式创建的,则必须在创建时传入期望的边框矩形。除了屏幕矩形之外,没有理由传入其它边框矩形。屏幕矩形可以通过UIScreen对象来取得,具体代码如下所示:

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

self.window.rootViewController = viewController;

//UIWindow有一个根视图控制器—这个视图控制器负责配置当窗体显示时最先显示的视图。

[self.window makeKeyAndVisible];
//这行代码会让包含了视图控制器视图的Window窗口显示在屏幕上。
```

#### 一、UIWindow是一种特殊的UIView,通常在一个程序中只会有一个UIWindow,但可以手动创建多个UIWindow,同时加到程序里面。UIWindow在程序中主要起到三个作用:

  1、作为容器,包含app所要显示的所有视图

  2、传递触摸消息到程序中view和其他对象

  3、与UIViewController协同工作,方便完成设备方向旋转的支持

#### 二、通常我们可以采取两种方法将view添加到UIWindow中:

  1、addSubview

  直接将view通过addSubview方式添加到window中,程序负责维护view的生命周期以及刷新,但是并不会为去理会view对应的ViewController,因此采用这种方法将view添加到window以后,我们还要保持view对应的ViewController的有效性, 不能过早释放。

  2、rootViewController

  rootViewController时UIWindow的一个遍历方法,通过设置该属性为要添加view对应的ViewController,UIWindow将会自动将其view添加到当前window中,同时负责ViewController和view的生命周期的维护,防止其过早释放

#### 三、WindowLevel

  UIWindow在显示的时候会根据UIWindowLevel进行排序的,即Level高的将排在所有Level比他低的层级的前面。下面我们来看UIWindowLevel的定义:
  
```
  UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal;
  UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert;
  UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatusBar __TVOS_PROHIBITED;
  typedef CGFloat UIWindowLevel;
```
    
iOS系统中定义了三个window层级,其中每一个层级又可以分好多子层级(从UIWindow的头文件中可以看到成员变量CGFloat _windowSublevel;),不过系统并没有把则个属性开出来。UIWindow的默认级别是UIWindowLevelNormal,我们打印输出这三个level的值分别如下:

```
NSLog(@"%f %f %f",UIWindowLevelAlert,UIWindowLevelNormal,UIWindowLevelStatusBar);
//2000.000000 0.000000 1000.000000
```

  window在创建的时候,默认是UIWindowLevelNormal(0.0),这个值越大,层次越靠上,也就是说

windowLevel大于0,小于1000的时候,在statusbar之下,在默认的window之上
windowLevel大于1000的时候,就在statusbar之上了。
  
#### 四、keywindow

  keyWindow是获取键盘和其他非触摸事件的window,同一时间只能有一个window为keywindow。所以,如果自己创建的Window要相应除触摸外的事件,要设置为keyWindow

方法

- (void)becomeKeyWindow; // 不可直接调用
- (void)resignKeyWindow; // 不可直接调用

- (void)makeKeyWindow;
- (void)makeKeyAndVisible; // 大部分apps 通过调用这个方法显示主window并将window设为key,否则用视图的隐藏属性
- (void)sendEvent:(UIEvent *)event; // 通过UIApplication 调用来分发任务给window 中的视图

- (CGPoint)convertPoint:(CGPoint)point toWindow:(UIWindow *)window; // 把该window中的一个坐标转换成在目标window中时的坐标值
- (CGPoint)convertPoint:(CGPoint)point fromWindow:(UIWindow *)window; // 把目标window中的一个坐标转换成在该window中时的坐标值
- (CGRect)convertRect:(CGRect)rect toWindow:(UIWindow *)window; // 把该window中的一个矩阵转换成在目标window中时的矩阵值
- (CGRect)convertRect:(CGRect)rect fromWindow:(UIWindow *)window;// 把目标window中的一个矩阵转换成在该window中时的矩阵值
常量

监测window的通知名称:

```
UIKIT_EXTERN NSString *const UIWindowDidBecomeVisibleNotification; // 当window激活时并展示在界面的时候触发,返回空
UIKIT_EXTERN NSString *const UIWindowDidBecomeHiddenNotification; // 当window隐藏的时候触发,暂时没有实际测,返回空
UIKIT_EXTERN NSString *const UIWindowDidBecomeKeyNotification; // 当window被设置为keyWindow时触发,返回空
UIKIT_EXTERN NSString *const UIWindowDidResignKeyNotification; // 当window的key位置被取代时触发,返回空
```
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: