回到AppDelegate重新创建一个uitabbarcontroller

时间:2011-07-21 21:29:03

标签: objective-c xcode uiviewcontroller uinavigationcontroller uitabbarcontroller

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

重复:

  1. 用户登录 - >第一个视图是标签栏视图
  2. 用户已退出 - >欢迎屏幕视图 - >登录/注册屏幕视图 - >标签栏视图
  3. 我正在寻找的是我需要在这个动作方法中写一下,一旦用户点击登录页面中的“登录”,就会调用该方法:

    -(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];   
    }
    

2 个答案:

答案 0 :(得分:2)

您可以考虑许多选项。

使用委托可以轻松实现这一目标。如果要关闭以模态方式呈现的VC,请为其指定delegate属性。代表将在需要时发送消息,让它解雇VC。使用委托的一个好方法是编写自定义的procotol。

例如:

// the delegate will conform to this protocol
@protocol SignInVCDelegate

// this method will be called when required
//
-(void)signInCompleted;

@end

现在,让你想要的对象符合该协议,例如app delegate。

// .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一个委托属性,该属性将在以模态方式呈现之前设置,并在登录过程完成时向委托发送消息。

// in .h
@property(retain) id <SignInDelegate>delegate;

// in .m
@synthesize delegate;

-(IBAction)validateSignIn {
    ...
    [delegate signInCompleted];
}

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

另一个简单的选择是使用通知。只要注册了该选项,该选项就可以在发生任何事情时通知任何对象。给定与前一个示例相同的对象,app委托将注册通知,而登录视图控制器将发布通知。

// 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中代理人和通知的更多信息。

答案 1 :(得分:1)

您可以尝试在您知道用户已成功登录的方法中执行此类操作。(假设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];