内容简介:最近产品要做一个消息的通知,而且通知是覆盖在 StatusBar 上面的。如果是普通的 UIView 则肯定是不行的,因为 StatusBar 为系统全局性的视图,所以要想覆盖它,则必须为 Statusbar 类型的,那么也就是 UIWindow 了。window等级,即window在z轴上的层级关系,默认是0。UIWindowLevel 本身是一个 CGFloat 类型,可以随意设置或进行加减,高等级会显示在低等级上面。系统给出了三种常用等级:这样创建的与 statusbar 大小一样的UIWindow
最近产品要做一个消息的通知,而且通知是覆盖在 StatusBar 上面的。如果是普通的 UIView 则肯定是不行的,因为 StatusBar 为系统全局性的视图,所以要想覆盖它,则必须为 Statusbar 类型的,那么也就是 UIWindow 了。
UIWindow 的基础介绍
- UIWindow是一种特殊的UIView,通常在一个app中至少会有一个UIWindow。
- iOS程序启动完毕后,创建的第一个视图控件就是UIWindow,接着创建控制器的View,最后将控制器的View添加到UIWindow上,于是控制器的View就显示在屏幕上了。
- 一个iOS程序之所以能显示在屏幕上,完全是因为它有UIWindow,也就是说,没有UIWindow就看不到任何UI界面。
- 状态栏和键盘都是特殊的UIWindow。
这里有三个重要的对象UIScreen,UIWindow,UIView。
- UIScreen对象识别物理屏幕连接到设备
- UIWindow对象提供绘画支持给屏幕
- UIView执行绘画,当窗口要显示内容的时候,UIView绘画出他们的内容并附加到窗口上。
UIWindow 等级
window等级,即window在z轴上的层级关系,默认是0。UIWindowLevel 本身是一个 CGFloat 类型,可以随意设置或进行加减,高等级会显示在低等级上面。系统给出了三种常用等级:
UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal; 0 UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert; 2000 UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatusBar; 4000
初始化 UIWindow 覆盖 StatusBar
-(void)initWindow { //初始化statusView,可在其上添加控件 CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame; stateWindow = [[UIWindow alloc] initWithFrame:statusBarFrame]; // 设置windowLevel为statusbar + 1 保证可以显示在statusbar上面 stateWindow.windowLevel = UIWindowLevelStatusBar + 1; stateWindow.backgroundColor = [UIColor orangeColor]; stateWindow.userInteractionEnabled = NO; }
这样创建的与 statusbar 大小一样的UIWindow 已经好了,默认创建好 这个UIWindow 则已经添加上去了,只是默认不显示,可以使用下面来控制显示和隐藏。
window.hidden = YES; window.hidden = NO;
当然 UIwindow 还有个 makeKeyAndVisible
方法,这个方法会将新建的 UIWindow 设置为主窗口并显示,之后如果消失后,需要将原来的主窗口设置回来,不然会出现很多异常的问题,这里切记。
注意:控制新添加的 UIWindow 使用 hidden 来控制。尽量不要使用 makeKeyAndVisible
这里的 stateWindow 必须是私有变量或者全局变量,生命周期随所在控制器的生命周期。
添加Label
上面的 UIWindow 创建好了,那么要显示相关的提示文字,还需要添加 label,
label = [[UILabel alloc] initWithFrame:stateWindow.frame]; label.backgroundColor = [UIColor blackColor]; label.textColor = [UIColor whiteColor]; label.font=[UIFont systemFontOfSize:12]; label.textAlignment = NSTextAlignmentCenter; [stateWindow addSubview:label];
之后设置 label的文字即可进行对其内容控制。
旋转问题处理
上面弄完基本上都完成,但是在旋转屏幕后,发现显示还是在原来的位置上,无法跟随系统的状态栏一起旋转。需要对 Window 设置空的UIViewController后才会跟着状态栏旋转。
// 需要设置一个空的ViewController 不然旋转屏幕后,不会跟着旋转坐标系 stateWindow.rootViewController = [UIViewController new];
旋转后,又发现了新的问题,在新建的 UIWindow 根据的是一开始时的状态长宽,但是旋转为横屏时,尺寸会发生变化,所以在每次显示 statusWindow 时重新设置下frame的大小,如下:
CGRect newFrame = CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, STATUSBAR_HEIGHT); stateWindow.frame = newFrame; label.frame = newFrame;
这里不直接取 statusbar 的frame,因为在statusbar 隐藏时获取的长宽为0,所以上面设置时取值为宽度和statusbar的高度,高度在一开始进行获取保存进常量中。
综上:对于显示覆盖 statusbar 的 UIWindow 已经完成啦,
其他细节
当我们显示了之后一般需要在延迟几秒后进行隐藏,在 Android 中一般实用Handler进行,或者实用timer进行执行操作。那么 ios 中怎么实用呢? 请看如下方法:
//延迟 3s 后执行 hideStateMsg 方法。 [self performSelector:@selector(hideStateMsg) withObject:nil afterDelay:3.0]; -(void)hideStateMsg { stateWindow.hidden = YES; }
当然在执行之前可能还需要把之前的延时任务取消了,则有如下两种方法。
// 取消 self 对象中所有的延迟任务。 [NSObject cancelPreviousPerformRequestsWithTarget:self]; // 取消指定的函数的延迟执行操作。 [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(hideStateMsg) object:nil];
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
常用算法深入学习实录
张子言 / 电子工业出版社 / 2013-10 / 89.00元
对于任何一门编程语言来说,算法都是程序的“灵魂”。正是因为算法如此重要,所以笔者精心编写了本书,希望通过书中的内容引领广大读者一起探讨学习算法的奥秘,带领广大读者真正步入程序开发的高级世界。 本书共分15章,循序渐进、由浅入深地详细讲解算法的核心内容,并通过具体实例的实现过程演练各个知识点的具体用法。本书首先详细讲解算法的基础知识,剖析了将算法称为“程序灵魂”的原因。然后详细讲解算法技术的核......一起来看看 《常用算法深入学习实录》 这本书的介绍吧!