【问题标题】:Implementing a lock screen for iOS app为 iOS 应用程序实现锁屏
【发布时间】:2013-01-29 20:04:41
【问题描述】:

我正在开发一个需要“锁定屏幕”的应用,用户必须在其中输入密码才能访问存储在应用中的数据。

应用程序启动时和用户不活动几分钟后,应显示此锁定屏幕。

目前,我的故事板中有一个单独的 UIViewController,它没有连接到故事板中的任何其他视图。我知道我可以通过将 instantiateViewControllerWithIdentifier 发送到 [self storyboard] 来访问这个视图控制器。但是,这在应用委托中不起作用。

但我需要在应用代理尝试打开数据库之前从应用代理调用锁定屏幕。

什么是实现这个的好方法?

【问题讨论】:

  • 有几个passcode screen libraries on github。试一试。
  • 感谢您的提示!实际上我已经实现了锁屏本身,只是不知道如何访问它,但我现在想通了。

标签: ios storyboard appdelegate


【解决方案1】:

这可能是一个较晚的答案,但我必须为我的一位使用 Storyboard 的客户实施相同的要求。 You can download the full project from here。希望这可以帮助某人。

我创建了两个 Viewcontroller,一个是 MainView,另一个需要一个四位数的代码才能关闭。我在 MainView 和 BlockKeypadViewController 之间创建了一个模态 segue,并将其命名为“lockItSegue”。 在 MainView 上,我插入了一个调用“lockIt”方法的 RoundRectButton。 该方法只执行segue“lockItSegue”。

- (IBAction)lockIt:(id)sender 
{
    [self performSegueWithIdentifier:@"lockItSegue" sender:self];
}

在 BlockKeypadViewController.h 上,我创建了

//
//  BlockKeypadViewController.h
//  Consultablet
//
//  Created by EDGARD AGUIRRE ROZO on 22/03/13.
//  Copyright (c) 2013 Colombia Creative Software. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>

@interface BlockKeypadViewController : UIViewController
@property (strong, nonatomic) IBOutlet UILabel *wrongCodeLabel;//*codigoIncorrectoLabel;
@property (strong, nonatomic) IBOutlet UILabel *tryAgainLabel;//*trateNuevamenteLabel;

@property (strong, nonatomic) IBOutlet UILabel *digit1;//*caracter1;
@property (strong, nonatomic) IBOutlet UILabel *digit2;//*caracter2;
@property (strong, nonatomic) IBOutlet UILabel *digit3;//*caracter3;
@property (strong, nonatomic) IBOutlet UILabel *digit4;//*caracter4;
@property int counter;//contador;
@property int codeIn;//claveIngresado;
@property int unlockCode;//claveDesbloqueo;
-(void) calculate:(int)number;//calcular:(int)numero;
- (IBAction)one:(id)sender;//uno:(id)sender;
- (IBAction)two:(id)sender;//dos:(id)sender;
- (IBAction)three:(id)sender;//tres:(id)sender;
- (IBAction)four:(id)sender;//cuatro:(id)sender;
- (IBAction)five:(id)sender;//cinco:(id)sender;
- (IBAction)six:(id)sender;//seis:(id)sender;
- (IBAction)seven:(id)sender;//siete:(id)sender;
- (IBAction)eight:(id)sender;//ocho:(id)sender;
- (IBAction)nine:(id)sender;//nueve:(id)sender;
- (IBAction)zero:(id)sender;//cero:(id)sender;
- (IBAction)cancel:(id)sender;//cancel:(id)sender;
-(void)checkCode;//verificarClave;

@end

在 BlockKeypadViewController.m 上:

//
//  BlockKeypadViewController.m
//  Consultablet
//
//  Created by EDGARD AGUIRRE ROZO on 22/03/13.
//  Copyright (c) 2013 Colombia Creative Software. All rights reserved.
//

#import "BlockKeypadViewController.h"
@implementation UILabel (My2)
//- (void)setImage:(UIImage *)image forState:(UIControlState)state animated:(BOOL)animated
- (void)setHidden:(BOOL)hidden animated:(BOOL)animated
{
    //[self setImage:image forState:state];
    [self setHidden:hidden];
    if (animated)
    {
        CATransition *animation = [CATransition animation];
        [animation setType:kCATransitionFade];
        [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
        [animation setFillMode:kCAFillModeBoth];
        [animation setDuration:.3];
        [[self layer] addAnimation:animation forKey:@"UILabelSetAnimationKey"];
    }
}
- (void)setHidden:(BOOL)hidden animated:(BOOL)animated seconds:(int)seconds
{
    //[self setImage:image forState:state];
    [self setHidden:hidden];
    if (animated)
    {
        CATransition *animation = [CATransition animation];
        [animation setType:kCATransitionFade];
        [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
        [animation setFillMode:kCAFillModeBoth];
        [animation setDuration:seconds];
        [[self layer] addAnimation:animation forKey:@"UILabelSetAnimationKey"];
    }
}
@end
@interface BlockKeypadViewController ()

@end

@implementation BlockKeypadViewController
@synthesize digit1,digit2,digit3,digit4,counter,codeIn,unlockCode,wrongCodeLabel,tryAgainLabel;

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.counter = 1;
    self.codeIn=0;

    self.unlockCode=1234;
    NSLog(@"Unlock Code %d",self.unlockCode);

    [digit1 setHidden:YES animated:YES];
    [digit2 setHidden:YES animated:YES];
    [digit3 setHidden:YES animated:YES];
    [digit4 setHidden:YES animated:YES];
}
-(void)checkCode
{
    if(self.codeIn==self.unlockCode)
    {
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    else
    {
        [wrongCodeLabel setHidden:NO animated:YES seconds:.1];
        [tryAgainLabel setHidden:NO animated:YES seconds:.1];
        [self.digit1 setHidden:YES animated:YES];
        [self.digit2 setHidden:YES animated:YES];
        [self.digit3 setHidden:YES animated:YES];
        [self.digit4 setHidden:YES animated:YES];
        self.codeIn = 0;

        NSLog(@"Wrong Code");
    }
}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}
-(void) calculate:(int)number
{
    if(self.counter==1)
    {
        [wrongCodeLabel setHidden:YES animated:YES seconds:.2];
        [tryAgainLabel setHidden:YES animated:YES seconds:.2];
        [self.digit1 setHidden:NO animated:YES];
        self.codeIn = number*1000;
    }
    if(self.counter==2)
    {
        [self.digit2 setHidden:NO animated:YES];
        self.codeIn = self.codeIn+number*100;
    }
    if(self.counter==3)
    {
        [self.digit3 setHidden:NO animated:YES];
        self.codeIn = self.codeIn+number*10;
    }
    if(self.counter==4)
    {
        [self.digit4 setHidden:NO animated:YES];
        self.codeIn = self.codeIn+number;
        [self performSelector:@selector(checkCode) withObject:nil afterDelay:0.2];
    }
    if(self.counter<4)
    {
        self.counter++;
    }
    else
    {
        self.counter=1;
    }
}
- (IBAction)one:(id)sender
{
    [self calculate:1];
}
- (IBAction)two:(id)sender
{
    [self calculate:2];
}
- (IBAction)three:(id)sender
{
    [self calculate:3];
}
- (IBAction)four:(id)sender
{
    [self calculate:4];
}
- (IBAction)five:(id)sender
{
    [self calculate:5];
}
- (IBAction)six:(id)sender
{
   [self calculate:6];
}
- (IBAction)seven:(id)sender
{
    [self calculate:7];
}
- (IBAction)eight:(id)sender
{
    [self calculate:8];
}
- (IBAction)nine:(id)sender
{
    [self calculate:9];
}
- (IBAction)zero:(id)sender
{
    [self calculate:0];
}
- (IBAction)cancel:(id)sender
{
    [self.digit1 setHidden:YES animated:YES];
    [self.digit2 setHidden:YES animated:YES];
    [self.digit3 setHidden:YES animated:YES];
    [self.digit4 setHidden:YES animated:YES];
    self.codeIn = 0;
    self.counter = 1;
}


@end

【讨论】:

    【解决方案2】:

    要从 appDelegate 在 HomeVC 上显示 lockVC,请使用:

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    HomeVC *hvc = [storyboard instantiateViewControllerWithIdentifier:@"HomeVC"];
    self.window.rootViewController = hvc;
    [self.window makeKeyAndVisible];
    
    LockVC *lvc = [storyboard instantiateViewControllerWithIdentifier:@"LockVC"] 
    [self.window.rootViewController presentViewController:lvc animated:YES completion:nil];
    

    【讨论】:

    • 恐怕这行不通。我收到此警告并且锁定屏幕未显示:'警告:尝试在 上显示 ,其视图不在窗口层次结构中!'
    • 出现此警告是因为您无法从 appDelegate 显示模态视图控制器。您需要从当前全屏显示的任何 viewController 中显示模态 ViewController。所以你应该首先在你的 appDelegate 中设置一个 window.rootViewController 然后从那个控制器调用这个代码。
    • 请注意,我已经编辑了答案,因此不会出现警告,但我仍然不建议这样做,您应该在 viewControllers 中显示锁定屏幕,而不是 didFinishLaunching:跨度>
    • 好的,我明白了。所以基本上,我的应用程序委托启动了导航控制器,它再次呈现了第一个视图控制器。从这个视图控制器我可以呈现这个模式锁屏。然后我只需要找到一种方法让应用程序委托在 didFinishLaunching 中等待,直到用户在锁定屏幕中输入密码。也许我可以移动代码以检查密码并将数据库打开到应用程序委托中的单独方法(不是 didFinishLaunching)并从锁定屏幕调用此方法?
    【解决方案3】:

    没有必要(我实际上不建议将它用于这只海豚)使用AppDelegate 来实现这个或任何LockScreen 解决方案。您应该创建一个从RootViewControllerLockScreen 的segue,并根据需要命名(例如lockItSegue)。然后从按钮动作调用[self performSegueWithIdentifier:@"lockItSegue" sender:self];LockScreen的逻辑(BlockKeypadViewController.m)上(一旦用户输入正确的代码),调用[self dismissViewControllerAnimated:YES completion:nil];

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-05
      • 2018-03-12
      • 2014-11-22
      • 2011-07-23
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      • 1970-01-01
      相关资源
      最近更新 更多