显示带有情节提要的一次性登录屏幕的最佳实践

Posted

技术标签:

【中文标题】显示带有情节提要的一次性登录屏幕的最佳实践【英文标题】:Best practice on showing a one time login screen w/ storyboards 【发布时间】:2012-01-30 14:14:37 【问题描述】:

我在这里看到过类似的问题,但没有明确的答案。所以我有一个带有经典用户名/密码表单的模式登录视图、一个 Facebook 登录按钮和一个注册按钮,我想在用户第一次启动应用程序时显示它们。根据我的发现,有两种方法可以实现这一点,但有缺点。

    在 AppDelegate 的 didFinishLaunchingWithOptions 中设置了一个条件来检查用户是否已登录。如果没有,则将 rootViewController 设置为 loginViewController。成功登录后,将转到应用程序的主视图。我对这种方法的问题是我不确定如何将 rootViewController 重置为主视图。这可能吗?如何实现?

有没有其他方法可以在不设置 rootViewController 的情况下显示登录模式?这意味着我会将 rVC 保留在主视图中。

    在 viewDidAppear 的主视图控制器中,有条件地检查用户是否已登录。如果没有,则执行 loginVC 的 segue。当用户成功登录时,他将返回到主视图,该主视图关闭了模式登录视图。这种方法的问题是主视图被简要显示,我不想这样做。

    还有其他想法吗?请让我知道在这种情况下最佳做法是什么。提前谢谢你,

【问题讨论】:

这里有一些很好的答案:***.com/questions/19962276/… 【参考方案1】:

在尝试了许多不同的方法后,我能够用这个来解决这个问题:

-(void)viewWillAppear:(BOOL)animated 

    // Check if user is already logged in
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    if ([[prefs objectForKey:@"log"] intValue] == 1) 
        self.view.hidden = YES;
    


-(void)viewDidAppear:(BOOL)animated
    [super viewDidAppear:animated];

    // Check if user is already logged in
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    if ([[prefs objectForKey:@"log"] intValue] == 1) 
        [self performSegueWithIdentifier:@"homeSeg3" sender:self];
    


-(void)viewDidUnload 
    self.view.hidden = NO;

【讨论】:

【参考方案2】:

在我看来,此类事情的最佳策略是在应用启动时已经在主视图控制器上显示的登录屏幕,并在用户登录后很好地关闭并释放。我发现大多数以前建议的解决方案(以及此处的建议:Best practices for Storyboard login screen, handling clearing of data upon logout)并不能很好地完成这一点。

经过昨天的一些实验,我认为最好的方法是使用子视图控制器:

1.像往常一样在 Xcode 中选择您的主界面故事板(无需向您的appDelegate添加任何内容@

2。将以下内容添加到 viewDidLoad 中的主视图控制器:

// If user is not logged in, show login view controller
if (!isLoggedIn) 
    // Instantiate Login View Controller from storyboard
    UIStoryboard *mainSB = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
    UIViewController *loginVC = [mainSB instantiateViewControllerWithIdentifier:@"Login"];

    // Set the Login View Controller's frame
    loginVC.view.frame = self.view.bounds;

    // Add login screen as a subview and as a child view controller
    [self.view addSubview:loginVC.view];
    [self addChildViewController:loginVC];
    [loginVC didMoveToParentViewController:self];

    // Maintain a reference to the Login screen so we can dismiss it later
    _loginVC = loginVC;

3.用户登录后,使用通知或委托通知您的主视图控制器。然后,您可以以任何您希望的方式为登录屏幕设置动画。这里我使用的是溶解动画:

// Animate out the category chooser
[UIView animateWithDuration:0.2 animations:^
    // Dissolve the login screen away
    [_loginVC.view setAlpha:0];
 completion:^(BOOL finished) 
    // Remove login screen as a child view controller
    [_loginVC willMoveToParentViewController:nil];
    [_loginVC.view removeFromSuperview];
    [_loginVC removeFromParentViewController];

    // nil out property
    _loginVC = nil;
];

就是这样!这样,主视图控制器始终是您窗口的根视图控制器,登录屏幕在用户登录后被释放,并且在首次显示登录屏幕时不会闪烁。

【讨论】:

【参考方案3】:

您可以通过 AppDelegate 设置 rootViewController,只需设置一个导航控制器,当您进行检查时,将导航控制器的根视图设置为您当时想要显示的任何视图。我认为如果你为你想要做的事情添加一个 if 语句,这样的事情应该可以工作:

// Override point for customization after application launch.
    RootViewController *rootController = [[RootViewController alloc] initWithNibName:nil bundle:nil];

    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootController];

    self.window.rootViewController = navigationController;

【讨论】:

是的,我知道在 appDelegate 中设置 rootViewController。我的问题是在登录到应用程序的主视图控制器后重置 rootViewController。不确定这是如何完成的,以及是否建议采用这种方法。 登录后为什么一定要rootViewController? 主要是为了让登录视图不在视图堆栈中。如果以后在开发中需要该选项,还能够执行诸如弹出所有视图控制器直到根目录的操作。 我很好奇您将如何在 iPad 上使用 UISplitViewController 作为根来执行此操作?

以上是关于显示带有情节提要的一次性登录屏幕的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

显示新视图控制器的最佳实践 (iPhone)

处理 UICollectionView 提要的侦听器的最佳实践

Firebase 云消息传递:最佳实践

ios 最佳实践 - 导航和选项卡控制器以及推送/弹出

以编程方式创建视图和添加子视图比使用情节提要更好/更快[重复]

iPAD GUI开发的最佳实践都有哪些