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

Dolly_洋的iOS的成长之路——UIWindow的理解与运用

2015-06-25 16:57 726 查看
说到UIWindow,首先要清楚以下几点:

1.UIWindow是最顶层的界面容器,并继承自UIView。

2.UIWindow基本方法,

显示:myWindow.hidden = NO;

消失:myWindow.hidden = YES;

[myWindow makeKeyWindow]; //将window设置成主keyWindow,是被系统设计用来接收键盘和其他非触摸事件的window。

[myWindow resignKeyWindow];

[myWindow makeKeyAndVisible];//相当于 [myWindow makeKeyWindow];myWindow.hidden = NO;

系统默认会有一个window,显示是用的- (void)makeKeyAndVisible;// convenience. most apps call this to show the main window and also make it key. otherwise use view hidden property.

这个方法,是为了更方便的让window显示并设置成keyWindow,否则,就要用前面说的[myWindow makeKeyWindow];myWindow.hidden = NO;这两行代码。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

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

[self.window setRootViewController:[[GesturePasswordController alloc] init]];

self.window.backgroundColor = [UIColor whiteColor];

[self.window makeKeyAndVisible];

return YES;

}

3.平常经常用到的UIWindow的情况:UIStatusbar 、 UIAlertView 、UIActionSheet 、键盘

首先,它们不是UIWindow!前面说了,UIWIndow是最顶层的界面容器,每当上面的控件出现的时候,系统会自动生成一个UIWindow,然后把这个视图加到相应的window中,再让window显示。仔细体会一下以上控件出现时的效果,是不是觉得UIWindow也不是那么抽象了呢。

现在,我们思考一个问题,当UIAlertView执行show的方法时,为什么会出现在最上层呢,系统不是有一个默认的window了吗,对,现在就要讲UIWindow的层级(UIWindowLevel)的概念。

4.UIWindowLevel

UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal;

UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert;

UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatusBar;

NSLog(@"UIWindowLevelNormal = %f,UIWindowLevelStatusBar = %f,UIWindowLevelAlert = %f",UIWindowLevelNormal,UIWindowLevelStatusBar,UIWindowLevelAlert);

输出一下这三个值会发现UIWindowLevelNormal = 0.000000

UIWindowLevelStatusBar = 1000.000000

UIWindowLevelAlert = 2000.000000

默认程序的window的windowLevel属性是UIWindowLevelNormal,UIAlertView对应的window.windowLevel = UIWindowLevelAlert,这就说明了哪个window层级越大,哪个window就会被显示在界面最上面。

当然,如果你想创建个window,让它还在UIAlertView之上,只需window.windowLevel = 2001.000000; //层级比alertVIew大,会覆盖在界面最上层。

5.思考下什么情况我们需要自己创建window。我们想一个场景,比如支付宝,在任何界面每次按Home键退出,再进来,就需要重新输入手势密码。这就很适合用UIWindow做,因为这个界面有可能从任何界面弹出,并且盖到所有界面的最上层,当然,也有其他的办法,下面就是实例代码(手势密码用的GesturePassword,https://github.com/smilingxinyi/GesturePassword)

//自定义继承自window的类声明部分

#import <UIKit/UIKit.h>

#import <Security/Security.h>

#import <CoreFoundation/CoreFoundation.h>

#import "TentacleView.h"

#import "GesturePasswordView.h"

#import "KeychainItemWrapper.h"

@interface GesturePasswordVertifyWindow : UIWindow<VerificationDelegate>

+(GesturePasswordVertifyWindow*)sharedInstance;

-(void)show;

@end

//自定义继承自window的类实现部分

#import "GesturePasswordVertifyWindow.h"

static GesturePasswordVertifyWindow * sharedWindow = nil;

@implementation GesturePasswordVertifyWindow

{

NSString * password;

GesturePasswordView * gesturePasswordView;

}

+(GesturePasswordVertifyWindow*)sharedInstance{

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

sharedWindow = [[self alloc]initWithFrame:[UIScreen mainScreen].bounds];

});

return sharedWindow;

}

-(instancetype)initWithFrame:(CGRect)frame{

self = [super initWithFrame:frame];

if(self){

//取到之前设置的手势密码

KeychainItemWrapper * keychin = [[KeychainItemWrapper alloc]initWithIdentifier:@"Gesture" accessGroup:nil];

password = [keychin objectForKey:(__bridge id)kSecValueData];

//将验证手势密码的view添加到当前window

gesturePasswordView = [[GesturePasswordView alloc]initWithFrame:[UIScreen mainScreen].bounds];

[gesturePasswordView.tentacleView setRerificationDelegate:self];

[gesturePasswordView.tentacleView setStyle:1];

[self addSubview:gesturePasswordView];

}

return self;

}

-(void)show{

//当重新进入程序时,调用show方法,显示当前window,覆盖到整个界面之上,起到安全的作用

[self makeKeyWindow]; //这里可以不设置成keyWindow,但是如果window需要弹出键盘了必须设置,

self.hidden = NO;

}

#pragma mark --- VerificationDelegate代理方法

- (BOOL)verification:(NSString *)result{

if ([result isEqualToString:password]) {

[gesturePasswordView.state setTextColor:[UIColor colorWithRed:2/255.f green:174/255.f blue:240/255.f alpha:1]];

[gesturePasswordView.state setText:@"输入正确"];

//密码正确当前window消失

[self resignKeyWindow];

self.hidden = YES;

return YES;

}

else{

[gesturePasswordView.state setTextColor:[UIColor redColor]];

[gesturePasswordView.state setText:@"手势密码错误"];

return NO;

}

}

@end

我们只需要在应用进入前台的回调函数中,调用该window的show方法即可,代码如下:

-(void)applicationDidBecomeActive:(UIApplication*)application{

[[ GesturePasswordVertifyWindow sharedInstance]show];

}

还有很多种情况也可以使用UIWindow,比如广告,启动页等,就不一一介绍了。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: