UIWindow
UIWindow.h文件
1、 IOS
/Applications//Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIWindow.h
/Applications//Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIWindow.h
一、UIWindow介绍
[1]、UIWindow是一种特殊的UIView(视图集合中的根view),每个UIWindow都有一个窗口等级(windowlevel),通常在一个程序中只会有一个UIWindow,可以手动创建多个UIWindow。UIWindow在程序中主要起到三个作用:
1、作为容器,包含app显示的所有视图
2、传递触摸消息到程序中view和其他对象
3、与UIViewController协同工作,方便完成设备方向旋转的支持
[2]、通常我们可以采取两种方法将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的生命周期的维护,防止其过早释放。
3、keyWindow : BOOL 类型,只读,用于判断是否是当前应用的 key window (key window 是指可接收到键盘输入及其他非触摸事件的 UIWindow,一次只能有一个 key window)
4、windowLevel :UIWindowLevel 类型,多个 UIWindow 的显示顺序是按照 windowLevel 从高到低排列的,windowLevel 最高的显示在最前面。比如:windowLevel 较高的 UIAlertView 警告窗口会显示在一般窗口的前面。UIWindowLevel 类型的定义如下:
typedef CGFloat UIWindowLevel;
UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal; //默认等级
UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert; //UIAlert等级
UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatsBar; //状态栏等级
打印结果如下:
NSLog(@"%f", UIWindowLevelNormal);
NSLog(@"%f", UIWindowLevelAlert);
NSLog(@"%f", UIWindowLevelStatusBar);
2013-03-16 10:00:48.925 iosDemo[1033:11303] 0.000000
2013-03-16 10:00:48.927 iosDemo[1033:11303] 2000.000000
2013-03-16 10:00:48.927 iosDemo[1033:11303] 1000.000000
5、makeKeyWindow :将当前 UIWindow 设置成应用的 key window。
6、makeKeyAndVisible :将当前 UIWindow 设置成应用的 key window,并使得 UIWindow 可见;也可以使用 UIView 的 hidden 属性来显示或者隐藏一个 UIWindow。
1、- (void)becomeKeyWindow; // override point for subclass. Do not call directly 调用窗口,使之变成关键窗口
2、- (void)resignKeyWindow; // override point for subclass. Do not call directly 调用窗口,使之取消关键窗口
3、- (void)makeKeyWindow; 使之成为主窗口
4、- (void)makeKeyAndVisible; // convenience. most apps call this to show the main window and also make it key. otherwise use view hidden property 使之成为主窗口,并且显示
5、- (void)sendEvent:(UIEvent *)event; // called by UIApplication to dispatch events to views inside the window 事件拦截分发到指定视图对象
当用户发起一个事件,比如触摸屏幕或者晃动设备,系统产生一个事件,同时投递给UIApplication,而UIApplication则将这个事件传递给特定的UIWindow进行处理(正常情况都一个程序都只有一个UIWindow),然后由UIWindow将这个事件传递给特定的对象(即first responder)并通过响应链进行处理。虽然都是通过响应链对事件进行处理,但是触摸事件和运动事件在处理上有着明显的不同(主要体现在确定哪个对象才是他们的first responder):
窗口坐标系统转化
6、- (CGPoint)convertPoint:(CGPoint)point toWindow:(UIWindow *)window; // can be used to convert to another window 转化当前窗口一个坐标相对另外一个窗口的坐标
7、- (CGPoint)convertPoint:(CGPoint)point fromWindow:(UIWindow *)window; // pass in nil to mean screen 转化另外窗口一个坐标相对于当前窗口的坐标
8、- (CGRect)convertRect:(CGRect)rect toWindow:(UIWindow *)window; 转化当前窗口一个矩形坐标相对另外一个窗口的坐标
9、- (CGRect)convertRect:(CGRect)rect fromWindow:(UIWindow *)window; 转化另外窗口一个矩形坐标相对于当前窗口的坐标
二 、UIWindow.h分析
// UIWindow.h // UIKit // // Copyright (c) 2005-2012, Apple Inc. All rights reserved. // #import <Foundation/Foundation.h>基础框架入口 #import <CoreGraphics/CoreGraphics.h>绘图入口 #import <UIKit/UIView.h>视图对象 #import <UIKit/UIApplication.h>提供IOS程序运行期的协作和控制 #import <UIKit/UIKitDefines.h>一些宏定义 typedef CGFloat UIWindowLevel; 32位则为float | 64位为double @class UIEvent, UIScreen, NSUndoManager, UIViewController; //UIEvent 触摸事件,运动事件 //UIScreen 屏幕处理 //NSUndoManager 记录撤销,修改操作的消息//UIViewController 视图控制器 NS_CLASS_AVAILABLE_IOS(2_0) @interface UIWindow : UIView { @package id _delegate; CGFloat _windowLevel; CGFloat _windowSublevel; id _layerContext; UIView *_lastMouseDownView; UIView *_lastMouseEnteredView; UIResponder *_firstResponder; id _fingerInfo; id _touchData; UIInterfaceOrientation _viewOrientation; UIView *_exclusiveTouchView; NSUndoManager *_undoManager; UIScreen *_screen; CALayer *_transformLayer; NSMutableArray *_rotationViewControllers; UIViewController *_rootViewController; UIColor *_savedBackgroundColor; NSMutableSet *_subtreeMonitoringViews; NSMutableSet *_tintViews; id _currentTintView; struct { unsigned int delegateWillRotate:1; unsigned int delegateDidRotate:1; unsigned int delegateWillAnimateFirstHalf:1; unsigned int delegateDidAnimationFirstHalf:1; unsigned int delegateWillAnimateSecondHalf:1; unsigned int autorotatesToPortrait:1; unsigned int autorotatesToPortraitUpsideDown:1; unsigned int autorotatesToLandscapeLeft:1; unsigned int autorotatesToLandscapeRight:1; unsigned int dontBecomeKeyOnOrderFront:1; unsigned int output:1; unsigned int inGesture:1; unsigned int bitsPerComponent:4; unsigned int autorotates:1; unsigned int isRotating:1; unsigned int isUsingOnePartRotationAnimation:1; unsigned int isHandlingContentRotation:1; unsigned int disableAutorotationCount:4; unsigned int needsAutorotationWhenReenabled:1; unsigned int forceTwoPartRotationAnimation:1; unsigned int orderKeyboardInAfterRotating:1; unsigned int roundedCorners:4; unsigned int resizesToFullScreen:1; unsigned int keepContextInBackground:1; unsigned int ignoreSetHidden:1; unsigned int forceVisibleOnInit:1; unsigned int settingFirstResponder:1; unsigned int legacyOrientationChecks:1; unsigned int windowResizedToFullScreen:1; } _windowFlags; id _windowController; } @property(nonatomic,retain) UIScreen *screen NS_AVAILABLE_IOS(3_2); // default is [UIScreen mainScreen]. changing the screen may be an expensive operation and should not be done in performance-sensitive code @property(nonatomic) UIWindowLevel windowLevel; // default = 0.0 @property(nonatomic,readonly,getter=isKeyWindow) BOOL keyWindow; - (void)becomeKeyWindow; // override point for subclass. Do not call directly 调用窗口,使之变成关键窗口 - (void)resignKeyWindow; // override point for subclass. Do not call directly 调用窗口,使之取消关键窗口 - (void)makeKeyWindow; 使之成为主窗口 - (void)makeKeyAndVisible; // convenience. most apps call this to show the main window and also make it key. otherwise use view hidden property 使之成为主窗口,并且显示 @property(nonatomic,retain) UIViewController *rootViewController NS_AVAILABLE_IOS(4_0); // default is nil - (void)sendEvent:(UIEvent *)event; // called by UIApplication to dispatch events to views inside the window 事件拦截分发到指定视图对象 当用户发起一个事件,比如触摸屏幕或者晃动设备,系统产生一个事件,同时投递给UIApplication,而UIApplication则将这个事件传递给特定的UIWindow进行处理(正常情况都一个程序都只有一个UIWindow),然后由UIWindow将这个事件传递给 特定的对象(即first responder) 并通过响应链进行处理。虽然都是通过响应链对事件进行处理,但是触摸事件和运动事件在处理上有着明显的不同(主要体现在确定哪个对象才是他们的first responder): 窗口坐标系统转化 - (CGPoint)convertPoint:(CGPoint)point toWindow:(UIWindow *)window; // can be used to convert to another window 转化一个坐标到另外窗口 - (CGPoint)convertPoint:(CGPoint)point fromWindow:(UIWindow *)window; // pass in nil to mean screen 转化一个坐标从另外窗口 - (CGRect)convertRect:(CGRect)rect toWindow:(UIWindow *)window; 转化一个矩形到另外窗口 - (CGRect)convertRect:(CGRect)rect fromWindow:(UIWindow *)window; 转化一个矩形从另外窗口 @end UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal; 默认等级 UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert; UIAlert等级 UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatusBar; 状态栏等级 UIKIT_EXTERN NSString *const UIWindowDidBecomeVisibleNotification; // nil 通知对象窗口为可见 UIKIT_EXTERN NSString *const UIWindowDidBecomeHiddenNotification; // nil通知对象窗口为隐藏 UIKIT_EXTERN NSString *const UIWindowDidBecomeKeyNotification; // nil 通知对象窗口为重要 UIKIT_EXTERN NSString *const UIWindowDidResignKeyNotification; // nil 通知对象窗口取消主窗口状态 // Each notification includes a nil object and a userInfo dictionary containing the // begining and ending keyboard frame in screen coordinates. Use the various UIView and // UIWindow convertRect facilities to get the frame in the desired coordinate system. // Animation key/value pairs are only available for the "will" family of notification. UIKIT_EXTERN NSString *const UIKeyboardWillShowNotification;通知键盘对象视图即将加载 UIKIT_EXTERN NSString *const UIKeyboardDidShowNotification; 通知键盘对象视图完全加载 UIKIT_EXTERN NSString *const UIKeyboardWillHideNotification; 通知键盘对象视图即将隐藏 UIKIT_EXTERN NSString *const UIKeyboardDidHideNotification; 通知键盘对象视图完全隐藏 UIKIT_EXTERN NSString *const UIKeyboardFrameBeginUserInfoKey NS_AVAILABLE_IOS(3_2); // NSValue of CGRect 指明键盘动画之前的框架,键盘将要显示时,显示之前把框架传递给这个动画;键盘已经显示即将隐藏时,键盘消失之前将这个框架传递给一个隐藏动画。包含一个CGRct类型值。 UIKIT_EXTERN NSString *const UIKeyboardFrameEndUserInfoKey NS_AVAILABLE_IOS(3_2); // NSValue of CGRect 指明动画完成后的键盘框架,键盘将要显示时,键盘完全显示后把框架传递给键盘;键盘已经显示即将隐藏时,键盘隐藏后将这个框架传递给一个键盘。包含一个CGRct类型值。 UIKIT_EXTERN NSString *const UIKeyboardAnimationDurationUserInfoKey NS_AVAILABLE_IOS(3_0); // NSNumber of double 指明键盘显示和隐藏动画所用时间,包好一个NSNumber类型值(double) UIKIT_EXTERN NSString *const UIKeyboardAnimationCurveUserInfoKey NS_AVAILABLE_IOS(3_0); // NSNumber of NSUInteger (UIViewAnimationCurve)指明动画类型,用来显示和隐藏键盘,包含了一个NSnumber类型值(NSUInteger) // Like the standard keyboard notifications above, these additional notifications include // a nil object and begin/end frames of the keyboard in screen coordinates in the userInfo dictionary. UIKIT_EXTERN NSString *const UIKeyboardWillChangeFrameNotification NS_AVAILABLE_IOS(5_0);键盘即将改变布局发出通知 UIKIT_EXTERN NSString *const UIKeyboardDidChangeFrameNotification NS_AVAILABLE_IOS(5_0);键盘已经改变布局后发出通知 // These keys are superseded by UIKeyboardFrameBeginUserInfoKey and UIKeyboardFrameEndUserInfoKey. UIKIT_EXTERN NSString *const UIKeyboardCenterBeginUserInfoKey NS_DEPRECATED_IOS(2_0, 3_2); 键盘开始动画之前的起始坐标 UIKIT_EXTERN NSString *const UIKeyboardCenterEndUserInfoKey NS_DEPRECATED_IOS(2_0, 3_2); 键盘动画后的坐标 UIKIT_EXTERN NSString *const UIKeyboardBoundsUserInfoKey NS_DEPRECATED_IOS(2_0, 3_2); 包含的矩形只能用于取得尺寸信息