改篇是介绍一个类似于支付宝返回Home重新打开后手势解锁,不同的是改篇介绍的解锁方法是输入密码,而不是手势解锁,下次有机会在单独写一篇手势解锁的实战介绍。
涉及到的知识点
- UIWindow
- AutoLayout
- UIButton,UITextField
- AppDelegate
开发
基本思路:
当按下Home按钮时,App进入后台,在进入后台的代码出将锁屏界面Show出来,解锁成功后,锁屏界面消失。这里的锁屏界面我用UIWindow来编写。
编写UIWidow锁屏界面
1.首先新建一个继承UIWindow的类,我在这个项目中取名为LockScreen。
2.LockScreen设计成一个单例模型。
.h文件中添加两个方法,单例和show。
#LockScreen.h
@interface LockScreen : UIWindow
+(id)shareInstance;
-(void)show;
@end
初始化代码
#LockScreen.m
+(id)shareInstance
{
static dispatch_once_t once;
static LockScreen * unlockWindow = nil;
dispatch_once(&once, ^{
unlockWindow = [[LockScreen alloc] initWithFrame:[UIScreen mainScreen].bounds];
});
return unlockWindow;
}
-(instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.windowLevel = UIWindowLevelAlert;
[self setBackgroundColor:[UIColor groupTableViewBackgroundColor]];
[self addSubview:self.passwordField];
[self addSubview:self.doneButton];
}
return self;
}
上面代码中,有一个windowLevel的属性,这个是设置UIWindow所在的层级,系统提供了三种层级,也可以自定义层级,因为改值是一个long类型的
UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal; //最下层
UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert; //最上层
UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatusBar; //中间层
3.添加两个控件(UITextField,UIButton)
-(UITextField *)passwordField
{
if (!_passwordField) {
_passwordField = [[UITextField alloc]init];
_passwordField.secureTextEntry = YES;
_passwordField.placeholder = @"请输入密码";
_passwordField.backgroundColor = [UIColor whiteColor];
}
return _passwordField;
}
-(UIButton *)doneButton
{
if (!_doneButton) {
_doneButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[_doneButton addTarget:self
action:@selector(tapButton:)
forControlEvents:UIControlEventTouchUpInside];
[_doneButton setTitle:@"确定" forState:UIControlStateNormal];
[_doneButton setBackgroundColor:[UIColor lightGrayColor]];
}
return _doneButton;
}
#pragma mark - button status
-(IBAction)tapButton:(id)sender
{
if ([self.passwordField.text isEqualToString:@"abc123"]) {
[self resignKeyWindow];
self.hidden = YES;
}
else
{
UIAlertView * alter = [[UIAlertView alloc] initWithTitle:@"Warning" message:@"password error" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alter show];
}
}
如果密码输错,则弹出警告框。
4.给控件设置constrain而不是使用setFrame
当然也可以用setFrame来定义控件的尺寸,但是autolayout能更好的适配不同尺寸的屏幕。关于autolayout的介绍请戳这里
#pragma mark - text field delegate
-(void)configConstrain
{
UITextField * passwordTextField = self.passwordField;
UIButton * doneButton = self.doneButton;
passwordTextField.translatesAutoresizingMaskIntoConstraints = NO;
doneButton.translatesAutoresizingMaskIntoConstraints = NO;
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[passwordTextField]-50-|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(passwordTextField)]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-100-[doneButton]-100-|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(doneButton)]];
CGFloat middleHeight = [UIScreen mainScreen].bounds.size.height/2;
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[passwordTextField(50)]-30-[doneButton(50)]-middleHeight-|" options:0 metrics:@{@"middleHeight":@(middleHeight)} views:NSDictionaryOfVariableBindings(passwordTextField,doneButton)]];
}
5.show LockScreen
-(void)show
{
[self makeKeyWindow];
[self configConstrain];
self.hidden = NO;
}
代码中makeKeyWindow是将该UIWindow设置为键盘可响应的状态。
在AppDelegate.m中添加代码
5.在AppDelegate.m中添加代码
- (void)applicationDidEnterBackground:(UIApplication *)application {
[[LockScreen shareInstance] show];
}
程序进入后台时,将锁屏界面show出来。
6.Bingo,运行^^
后记
UIWindow是UIView的子类,所以可以使用UIView中的方法,例如:addSubview等。
这次是密码锁屏界面,后面会在写一篇手势解锁的文章,该文章的源代码在github上。