【问题标题】:going back to AppDelegate to recreate a uitabbarcontroller回到 AppDelegate 重新创建一个 uitabbarcontroller
【发布时间】:2023-03-31 15:45:01
【问题描述】:

我有一个基于带有欢迎屏幕的标签栏视图的应用程序(导致登录或注册过程)。基本上,如果您已登录 - 您直接进入标签栏视图,如果没有,您将进入欢迎屏幕,您可以在其中选择登录或注册。假设您去登录或注册,我希望标签栏视图重新出现,但是,所有声明都在 AppDelegate 中。我怎样才能“返回”并调用 tabbatcontroller?我的课程结构/流程是否正确?

重复一遍:

  1. 用户登录 -> 第一个视图是标签栏视图
  2. 用户退出 -> 欢迎屏幕视图 -> 登录/向上屏幕视图 -> 选项卡栏视图

我正在寻找的是我需要在这个动作方法中写什么,一旦用户在登录页面中点击“登录”就会被调用:

-(IBAction)done:(id)sender {

?????

}

作为参考,我的 appDelegate 是:

  if(user signed in)
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIViewController *viewController1 = [[FirstTab alloc] initWithNibName:@"FirstTab" bundle:NSBundle.mainBundle];
UIViewController *viewController2 = [[SecondTab alloc] initWithNibName:@"SecondTab" bundle:NSBundle.mainBundle];
UINavigationController *secondNavController = [[UINavigationController alloc]initWithRootViewController:viewController2];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, secondNavController, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];

}
else
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    SigninTabBarTemplateViewController *landingPage = [[SigninTabBarTemplateViewController alloc] initWithNibName:@"SigninTabBarTemplateViewController" bundle:nil];
    self.window.rootViewController = (UIViewController *) landingPage;            
    [self.window makeKeyAndVisible];   
}

【问题讨论】:

    标签: objective-c xcode uiviewcontroller uinavigationcontroller uitabbarcontroller


    【解决方案1】:

    您可以考虑多种选择。

    这可以通过使用 delegate 轻松实现。如果你想关闭你以模态方式呈现的 VC,给它一个delegate 属性。代理将在需要时收到一条消息,让其解散 VC。使用委托的一个好方法是编写自定义协议。

    例如:

    // the delegate will conform to this protocol
    @protocol SignInVCDelegate
    
    // this method will be called when required
    //
    -(void)signInCompleted;
    
    @end
    

    现在,让您想要的对象符合该协议,例如应用委托。

    // .h
    #import "SignInVCDelegate.h"
    
    @interface YourAppDelegate : NSObject <..., SignInDelegate> {
        ...
        SignInVC *signIn;
        ...
    }
    
    -(void)signInCompleted;
    
    @end
    

    实现如下所示:

    // .m
    ...
    -(void)signInCompleted {
        ...
        [signIn.view removeFromSuperview];
    }
    
    -(BOOL)applicationDidFinishLaunching {
        if(!logged) {
            ...
            [signIn setDelegate:self];
            [self.tabBarController presentModalViewController:signIn
                                                     animated:YES];
        }
    }
    

    现在给signInVC一个delegate属性,它会在模态呈现之前设置,并在登录过程完成时向delegate发送消息。

    // in .h
    @property(retain) id <SignInDelegate>delegate;
    
    // in .m
    @synthesize delegate;
    
    -(IBAction)validateSignIn {
        ...
        [delegate signInCompleted];
    }
    

    你可以编写任何你想要的方法,这个例子很简单,给委托人一些信息是有用的。例如,在这种情况下,您可以传递用户名、用户 ID 或您想要的任何内容。

    另一个简单的选项是使用通知。此选项允许任何对象在发生某事时得到通知,只要它注册即可。给定与上一个示例相同的对象,应用程序委托将注册通知,而登录视图控制器将发布它。

    // in app delegate .m
    -(BOOL)applicationDidFinishLaunching {
        ...
        [[NSNotificationCenter defaultCenter]
         addObserver:self
            selector:@selector(signInCompleted)
                name:@"UserSignedInNotification"
              object:nil];
    }
    
    // in SignInVC.m
    -(IBAction)validateSignIn {
        ...
        [[NSNotificationCenter defaultCenter]
         postNotificationName:@"UserSignedInNotification"
                       object:self];
    }
    

    Communicating with Objects 中有关代表和通知的更多信息。

    【讨论】:

    • 谢谢文斯,我会尝试并报告。
    • 嘿@Vince - 你的例子中的 setDelegate 是什么?谢谢!
    • 嘿@Vince - 如果我在 AppDelegate 和登录之间有另一个页面,知道如何实施您的解决方案吗? (这是一个受欢迎的视图控制器)?谢谢!!
    • @TommyG - 我会为此使用计时器。只需首先显示您想要的视图并设置一个计时器,它将 1)删除欢迎视图 2)使用您的 tabBarController 为窗口设置 rootViewController 并以模态方式显示 VC 中的登录。
    • 这里...你介意我把我的代码发给你吗?我太绝望了...我在登录和注册页面中都实例化了 AppDelegate 做了一些奇怪的事情,这样我就可以调用 tabcontroller,但这听起来确实不对,尽管它有效。
    【解决方案2】:

    您可以尝试在您知道用户已成功登录的方法中执行此类操作。(假设 SignedInTabbarViewController 是您的 TabBarController)

       SignedInTabbarViewController *signedInTabbarViewController = [[SignedInTabbarViewController alloc] init];
       id mainDelegate = [[UIApplication sharedApplication] delegate];
       [self.navigationController.view removeFromSuperview];
       if( [mainDelegate respondsToSelector:@selector(setViewController:)]) {
           [mainDelegate setViewController:signedInTabbarViewController];
       }
       UIWindow   *mainWindow = [mainDelegate window];
       [mainWindow addSubview: signedInTabbarViewController.view];
      [signedInTabbarViewController release];
    

    【讨论】:

    • 你刚刚写的让我觉得我错过了一些重要的东西......我真的没有任何作为 TabBarController 的类 - 一切都在 AppDelegate (上图)中声明,我从 AppDelegate 去到 firstTabBar 对象(这是第一个选项卡的视图控制器)。所以我所有的类都是:AppDelegate、FirstTabViewController、SecondTabVireController、HomePage(带有登录/注册按钮、登录视图和注册视图。我需要一个单独的 TabBarController 类吗?
    • 如果你这样做会更容易。但是你在“用户登录”块中所做的也足够了。
    • 我不明白的是如何在 signInViewController 中做到这一点?我没有任何 TabBarController 对象可以调用...一切都在 AppDelegate 中!请帮忙.....:(
    • 您不应该将两个控制器都放在 AppDelegate 中。 @Vince 的建议是最好的方法。但是,如果您不想那样做,我建议您在 AppDelegate 中设置 SignInViewController,并在用户登录时设置您的 tabbarcontroller,删除 currentcontroller,然后将 tabbarcontroller 添加到 AppDelegate。
    猜你喜欢
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 2018-08-01
    • 1970-01-01
    相关资源
    最近更新 更多