gpt4 book ai didi

详解iOS设计中的UIWindow使用

转载 作者:qq735679552 更新时间:2022-09-28 22:32:09 25 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章详解iOS设计中的UIWindow使用由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

每一个ios程序都有一个uiwindow,在我们通过模板简历工程的时候,xcode会自动帮我们生成一个window,然后让它变成keywindow并显示出来。这一切都来的那么自然,以至于我们大部分时候都忽略了自己也是可以创建uiwindow对象。     通常在我们需要自定义uialertview的时候(ios 5.0以前alertview的背景样式等都不能换)我们可以使用uiwindow来实现(设置windowlevel为alert级别),网上有很多例子,这里就不详细说了。 1、uiwindowlevel     我们都知道uiwindow有三个层级,分别是normal,statusbar,alert。打印输出他们三个这三个层级的值我们发现从左到右依次是0,1000,2000,也就是说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 uiwindowlevelnormal;     。

  。

const uiwindowlevel uiwindowlevelalert;     。

const uiwindowlevel uiwindowlevelstatusbar;  。

   

  。

typedef cgfloat uiwindowlevel;   ios系统中定义了三个window层级,其中每一个层级又可以分好多子层级(从uiwindow的头文件中可以看到成员变量cgfloat _windowsublevel;),不过系统并没有把则个属性开出来。uiwindow的默认级别是uiwindowlevelnormal,我们打印输出这三个level的值分别如下:   。

?
1
2
3
4
5
2012-03-27 22:46:08.752 uiviewsample[395:f803] normal window level: 0.000000
 
2012-03-27 22:46:08.754 uiviewsample[395:f803] alert window level: 2000.000000
 
2012-03-27 22:46:08.755 uiviewsample[395:f803] status window level: 1000.000000

  。

  这样印证了他们级别的高低顺序从小到大为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 = uiwindowlevelnormal;
[normalwindow makekeyandvisible];

cgrect windowrect = cgrectmake(50,
50,
[[uiscreen mainscreen] bounds].size.width - 100,
[[uiscreen mainscreen] bounds].size.height - 100);
uiwindow *alertlevelwindow = [[uiwindow alloc] initwithframe:windowrect];
alertlevelwindow.windowlevel = uiwindowlevelalert;
alertlevelwindow.backgroundcolor = [uicolor redcolor];
[alertlevelwindow makekeyandvisible];

uiwindow *statuslevelwindow = [[uiwindow alloc] initwithframe:cgrectmake(0, 50, 320, 20)];
statuslevelwindow.windowlevel = uiwindowlevelstatusbar;
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最高的始终显示在最前面.

  。

2、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.viewcontroller;     [self.window makekeyandvisible];         uiwindow *window1 = [[uiwindow alloc] initwithframe:cgrectmake(0, 80, 320, 320)];     window1.backgroundcolor = [uicolor redcolor];     window1.windowlevel = uiwindowlevelalert;     [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 = uitextborderstyleroundedrect;
    [self.view addsubview:filed];
    [filed release];
}

  。

  运行截图如下: 从图中可以看出,虽然我们自己新建了一个然后设置为keywindow并显示,但是点击程序中默认window上添加的textfield还是可以唤出键盘,而且还可以正常接受键盘输入,只是键盘被挡住了,说明非keywindow也是可以接受键盘消息,这一点和文档上说的不太一样。     观察uiwindow的文档,我们可以发现里面有四个关于window变化的通知:      。

?
1
2
3
4
5
6
7
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];”的时候,控制台输出如下:   。

详解iOS设计中的UIWindow使用

keywindow的变化和window的显示和上面的流程一样,同时我们可以看出actionsheet的window的level是2001。     c、接着上一步,我们点击弹出actionsheet的cancel的时候,控制台输出如下:

我们看出流程如下:     1、首先actionsheet的window变成非keywindow     2、程序默认的window变成keywindow     3、actionsheet的window在隐藏掉     总体就是“想隐居幕后可以,但得先交出权利”.

最后此篇关于详解iOS设计中的UIWindow使用的文章就讲到这里了,如果你想了解更多关于详解iOS设计中的UIWindow使用的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com