ios中uiwindow keywindow和keywindow有什么区别

本帖子已过去太久远了,不再提供回复功能。详解iOS设计中的UIWindow使用
投稿:goldensun
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了iOS设计中的UIWindow使用,包括UIWindowLevel和KeyWindow两个大的方面的讲解,需要的朋友可以参考下
每一个IOS程序都有一个UIWindow,在我们通过模板简历工程的时候,xcode会自动帮我们生成一个window,然后让它变成keyWindow并显示出来。这一切都来的那么自然,以至于我们大部分时候都忽略了自己也是可以创建UIWindow对象。
  通常在我们需要自定义UIAlertView的时候(IOS 5.0以前AlertView的背景样式等都不能换)我们可以使用UIWindow来实现(设置windowLevel为Alert级别),网上有很多例子,这里就不详细说了。
一、UIWindowLevel
  我们都知道UIWindow有三个层级,分别是Normal,StatusBar,Alert。打印输出他们三个这三个层级的值我们发现从左到右依次是0,,也就是说Normal级别是最低的,StatusBar处于中等水平,Alert级别最高。而通常我们的程序的界面都是处于Normal这个级别上的,系统顶部的状态栏应该是处于StatusBar级别,UIActionSheet和UIAlertView这些通常都是用来中断正常流程,提醒用户等操作,因此位于Alert级别。
  上一篇文章中我也提到了一个猜想,既然三个级别的值之间相差1000,而且我们细心的话查看UIWindow的头文件就会发现有一个实例变量_windowSublevel,那我们就可以定义很多中间级别的Window。例如可以自定义比系统UIAlertView级别低一点儿的window。于是写了一个小demo,通过打印发现系统的UIAlertView的级别是1996,而与此同时UIActionSheet的级别是2001,这样也验证了subLevel的确存在。
&& UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Alert View"
message:@"Hello Wolrd, i'm AlertView!!!"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:@"Cancel", nil];
[alertView show];
[alertView release];
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"ActionSheet"
delegate:nil
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:@"Don't do that!"
otherButtonTitles:@"Hello Wolrd", nil];
[actionSheet showInView:self.view];
[actionSheet release];
  下面是程序运行截图:
根据window显示级别优先的原则,级别高的会显示在上面,级别低的在下面,我们程序正常显示的view位于最底层,至于具体怎样获取UIAlertView和UIActionSheet的level,我会在下面第二部分keyWindow中介绍并给出相应的代码。
UIWindow在显示的时候会根据UIWindowLevel进行排序的,即Level高的将排在所有Level比他低的层级的前面。下面我们来看UIWindowLevel的定义:
const UIWindowLevel UIWindowLevelN    
const UIWindowLevel UIWindowLevelA    
const UIWindowLevel UIWindowLevelStatusB    
typedef CGFloat UIWindowL
  IOS系统中定义了三个window层级,其中每一个层级又可以分好多子层级(从UIWindow的头文件中可以看到成员变量CGFloat _windowS),不过系统并没有把则个属性开出来。UIWindow的默认级别是UIWindowLevelNormal,我们打印输出这三个level的值分别如下:
22:46:08.752 UIViewSample[395:f803] Normal window level: 0.000000
22:46:08.754 UIViewSample[395:f803] Alert window level:
22:46:08.755 UIViewSample[395:f803] Status window level:
  这样印证了他们级别的高低顺序从小到大为Normal & StatusBar & Alert,下面请看小的测试代码:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.window.backgroundColor = [UIColor yellowColor];
[self.window makeKeyAndVisible];
UIWindow *normalWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
normalWindow.backgroundColor = [UIColor blueColor];
normalWindow.windowLevel = UIWindowLevelN
[normalWindow makeKeyAndVisible];
CGRect windowRect = CGRectMake(50,
[[UIScreen mainScreen] bounds].size.width - 100,
[[UIScreen mainScreen] bounds].size.height - 100);
UIWindow *alertLevelWindow = [[UIWindow alloc] initWithFrame:windowRect];
alertLevelWindow.windowLevel = UIWindowLevelA
alertLevelWindow.backgroundColor = [UIColor redColor];
[alertLevelWindow makeKeyAndVisible];
UIWindow *statusLevelWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0, 50, 320, 20)];
statusLevelWindow.windowLevel = UIWindowLevelStatusB
statusLevelWindow.backgroundColor = [UIColor blackColor];
[statusLevelWindow makeKeyAndVisible];
NSLog(@"Normal window level: %f", UIWindowLevelNormal);
NSLog(@"Alert window level: %f", UIWindowLevelAlert);
NSLog(@"Status window level: %f", UIWindowLevelStatusBar);
return YES;
  运行结果如下图:
我们可以注意到两点:
  1)我们生成的normalWindow虽然是在第一个默认的window之后调用makeKeyAndVisible,但是仍然没有显示出来。这说明当Level层级相同的时候,只有第一个设置为KeyWindow的显示出来,后面同级的再设置KeyWindow也不会显示。
  2)statusLevelWindow在alertLevelWindow之后调用makeKeyAndVisible,仍然只是显示在alertLevelWindow的下方。这说明UIWindow在显示的时候是不管KeyWindow是谁,都是Level优先的,即Level最高的始终显示在最前面。
二、KeyWindow
  什么是keyWindow,官方文档中是这样解释的"The key window is the one that is designated to receive keyboard and other non-touch related events. Only one window at a time may be the key window." 翻译过来就是说,keyWindow是指定的用来接收键盘以及非触摸类的消息,而且程序中每一个时刻只能有一个window是keyWindow。
  下面我们写个简单的例子看看非keyWindow能不能接受键盘消息和触摸消息,程序中我们在view中添加一个UITextField,然后新建一个alert级别的window,然后通过makeKeyAndVisible让它变成keyWindow并显示出来。代码如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
&&& self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
&&& // Override point for customization after application launch.
&&& self.viewController = [[[SvUIWindowViewController alloc] initWithNibName:@"SvUIWindowViewController" bundle:nil] autorelease];
&&& self.window.rootViewController = self.viewC
&&& [self.window makeKeyAndVisible];
&&& UIWindow *window1 = [[UIWindow alloc] initWithFrame:CGRectMake(0, 80, 320, 320)];
&&& window1.backgroundColor = [UIColor redColor];
&&& window1.windowLevel = UIWindowLevelA
&&& [window1 makeKeyAndVisible];
&&& return YES;
- (void)viewDidLoad
&&& [super viewDidLoad];
&&& // Do any additional setup after loading the view, typically from a nib.
&&& [self registerObserver];
&&& // add a textfield
&&& UITextField *filed = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 320, 60)];
&&& filed.placeholder = @"Input something here";
&&& filed.clearsOnBeginEditing = YES;
&&& filed.borderStyle = UITextBorderStyleRoundedR
&&& [self.view addSubview:filed];
&&& [filed release];
  运行截图如下:
从图中可以看出,虽然我们自己新建了一个然后设置为keyWindow并显示,但是点击程序中默认window上添加的textField还是可以唤出键盘,而且还可以正常接受键盘输入,只是键盘被挡住了,说明非keyWindow也是可以接受键盘消息,这一点和文档上说的不太一样。
  观察UIWindow的文档,我们可以发现里面有四个关于window变化的通知:
UIWindowDidBecomeVisibleNotification
  UIWindowDidBecomeHiddenNotification
  UIWindowDidBecomeKeyNotification
  UIWindowDidResignKeyNotification
  这四个通知对象中的object都代表当前已显示(隐藏),已变成keyWindow(非keyWindow)的window对象,其中的userInfo则是空的。于是我们可以注册这个四个消息,再打印信息来观察keyWindow的变化以及window的显示,隐藏的变动。
  代码如下:
根据打印的信息我们可以看出流程如下:
  1、程序默认的window先显示出来
  2、默认的window再变成keyWindow
  3、AlertView的window显示出来
  4、默认的window变成非keyWindow
  5、最终AlertView的window变成keyWindow
  总体来说就是“要想当老大(keyWindow),先从小弟(非keyWindow)开始混起” 而且根据打印的信息我们同事可以知道默认的window的level是0,即normal级别;AlertView的window的level是1996,比Alert级别稍微低了一点儿。
  b、当我们打开viewDidAppear中“[self presentActionSheet];”的时候,控制台输出如下:  
keyWindow的变化和window的显示和上面的流程一样,同时我们可以看出ActionSheet的window的level是2001。
  c、接着上一步,我们点击弹出ActionSheet的cancel的时候,控制台输出如下:
我们看出流程如下:
  1、首先ActionSheet的window变成非keyWindow
  2、程序默认的window变成keyWindow
  3、ActionSheet的window在隐藏掉
  总体就是“想隐居幕后可以,但得先交出权利”。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具Keywindow添加子视图不显示_IOS开发-织梦者
当前位置:&>&&>& > Keywindow添加子视图不显示
Keywindow添加子视图不显示
添加子视图在keywindow上不显示出来
调试发现[UIApplication sharedApplication].keyWindow 为nil不存在
究其原因 是因为这个时候appdelegate中的keywindow还没有创建出来
我们可以用[[[UIApplication sharedApplication] delegate] window]代替[UIApplication sharedApplication].keyWindow
这个问题在iOS7中经常容易出现,iOS8中苹果已经解决了这个问题
UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
[window addSubview: xx];
以上就是Keywindow添加子视图不显示的全文介绍,希望对您学习和使用ios应用开发有所帮助.
这些内容可能对你也有帮助
更多可查看IOS开发列表页。
猜您也会喜欢这些文章最近的项目里有个关于创建多个uiwindow时使用keywindow出现的bug。
有个任务是在打开信息展示时,要求不被任何东西遮挡。这里设计方案是添加一个新的HXUIWindow继承与UIWindow。测试时打开了HXUIWindow显示在屏幕上,执行打开 弹框 按钮(uiactionsheet或uialerview),当弹框消失后,再执行向主页最外层添加一个view,这个时候应该会想到用[[UIApplication sharedApplication].keyWindow addSubview:view],这个时候问题出现了,程序将view添加到了HXUIWindow上,而HXUIwindow大小只有100*100,所以超出的内容没有点击事件。
这是为什么呢?因为这个时候[UIApplication sharedApplication].keyWindow 是HXUIWindow而不是程序最开始默认的那个[[[UIApplication sharedApplication] delegate] window]。这又是为什么呢,因为这里执行了打开 弹框 按钮(uiactionsheet或uialerview),当打开(uiactionsheet或uialerview)时,程序为了让弹框出现在最外层,会新建一个临时的uiwindow,并且层级最高,还将keywindow赋值与它。当弹框消失后keywindow将转向另一个uiwindow,这个时候转向了HXUIWindow,因为HXUIWindow层级最高,在windows里层级拍最后面。刚开始的时候只有[[[UIApplication
sharedApplication] delegate] window],所以其为keywindow,当然也是有因为设置为keywindow的原因,只有添加HXUIWindow时没有改变keywindow的值,当弹窗弹出后keywindow会将指向弹框弹出后新建的uiwindow,弹窗消失时keywindow又将重新指向,这个时候其会将指向层级最高的uiwindow,所以指向了HXUIWindow了。
1.经过测试keyWindow永远是覆盖在视图的最外层,在正常情况下获取到的keyWindow是UIWindow;
&2.在有UIAlertView或UIActionSheet的弹出层情况下,在去获取keyWindow这个时keyWindow就会变成UIAlertControllerShimPresenterWindow这个类,是弹出层上层的一个window;
3.在UIAlertView或UIActionSheet弹出后再给keyWindow添加的view,会在UIAlertView弹出层消失后,keyWindow上边的视图也会随之消失;
4.会在UIAlertView弹出层消失后,keyWindow指向视图最外层的HXUIWindow了,之后添加到[[UIApplication sharedApplication].keyWindow 上的uiview都将添加到HXUIWindow上了;
本文已收录于以下专栏:
相关文章推荐
有时候,我们需要将View添加到最上层的Window上,比如:弹出框、Loading等,经常有同学直接通过:[[UIApplication sharedApplication].windows las...
昨天,遇到一个很奇葩的问题,看下面代码:
[objc] view
plain copy
-(void) alertView:(UIAlertView ...
[UIApplication sharedApplication].keyWindow 在iOS7中为nil 的解决方案
在rootViewController中的viewDidLoad:方法中调用[[UIApplication sharedApplication].keyWindow
addSubview:]
什么是KeyWindow?
查找应用程序的主窗口对象。一般情况就是UIWindow。当然一个应用程序可以有多个window,键盘是一个window,[[UIApplication sharedApplication] keyWi...
添加子视图在keywindow上不显示出来
调试发现[UIApplication sharedApplication].keyWindow 为nil不存在
究其原因 是因为这个时候appdelega...
一.有storyboard的项目创建过程
1.点击程序图标——&2.执行Main函数——&3.执行UIApplicationMain(),根据其第三个和第四个参数创建Application,创建代理...
Xcode8下创建一个project,在存在Main.storyboard并且AppDelegate的application: didFinishLaunchingWithOptions:没...
主窗口(key window)接受特定事件
  一个窗口当前能接受键盘和非触摸事件时,便被认为是主窗口。而触摸事件则被投递到触摸发生的窗口,没有相应坐标值的事件被投递到主窗口。同一时刻只有一个窗...
他的最新文章
讲师:王哲涵
讲师:韦玮
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)keyWindow与delegate中Window的区别
keyWindow与delegate中Window的区别
ViewController.m
UIWindowRelated
Created by YouXianMing on 14/10/25.
keyWindow与delegate中Window的区别
ViewController.m
UIWindowRelated
Created by YouXianMing on 14/10/25.
Copyright (c) 2014年 YouXianMing. All rights reserved.
#import "ViewController.h"
@interface ViewController ()
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"-------");
NSLog(@"%@", [UIApplication sharedApplication].keyWindow);
NSLog(@"%@", [[[UIApplication sharedApplication] delegate] window]);
- (void)viewDidAppear:(BOOL)animated {
NSLog(@"#######");
NSLog(@"%@", [UIApplication sharedApplication].keyWindow);
NSLog(@"%@", [[[UIApplication sharedApplication] delegate] window]);
结果如下图:
从打印结果中可以知道:
keyWindow与delegate中的window其实是一样的,keyWindow的存在的意义,其实就是为了说明当前的window接管了这个控制器的view而已,你可以在keyWindow上加载你自己的建立的view了。
现在提供一个便利的类目^_^:
UIWindow+Window.h
Created by YouXianMing on 14-10-10.
Copyright (c) 2014年 YouXianMing. All rights reserved.
#import &UIKit/UIKit.h&
@interface UIWindow (Window)
返回keyWindow(如果keyWindow有值,代表着你可以给window添加view了)
@return 可以添加view并显示出来的window(如果返回为nil,说明你不能将view添加到window上去显示)
+ (UIWindow *)usableW
返回window
@return window(你给这个window添加的view很有可能被控制器的view覆盖而显示不了)
+ (UIWindow *)rootW
UIWindow+Window.m
Created by YouXianMing on 14-10-10.
Copyright (c) 2014年 YouXianMing. All rights reserved.
#import "UIWindow+Window.h"
@implementation UIWindow (Window)
+ (UIWindow *)usableWindow
return [UIApplication sharedApplication].keyW
+ (UIWindow *)rootWindow
return [[[UIApplication sharedApplication] delegate] window];
版权声明:本文内容由互联网用户自发贡献,本社区不拥有所有权,也不承担相关法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至: 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
用云栖社区APP,舒服~
【云栖快讯】红轴机械键盘、无线鼠标等753个大奖,先到先得,云栖社区首届博主招募大赛9月21日-11月20日限时开启,为你再添一个高端技术交流场所&&
阿里云移动APP解决方案,助力开发者轻松应对移动app中随时可能出现的用户数量的爆发式增长、复杂的移动安全挑战等...
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本...
MaxCompute75折抢购
Loading...}

我要回帖

更多关于 ios 获取keywindow 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信