在主标签栏控制器之前显示登录视图控制器

22 iphone uitabbarcontroller uiviewcontroller ipad

我正在创建一个带有标签栏控制器的iPad应用程序,需要登录.所以在启动时,我想显示一个LoginViewController,如果登录成功,则显示标签栏控制器.这就是我实现初始测试版本的方法(遗漏了一些典型的标题内容等)......

AppDelegate.h:

@interface AppDelegate_Pad : NSObject 
        <UIApplicationDelegate, LoginViewControllerDelegate> {
    UIWindow *window;
    UITabBarController *tabBarController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
@end
Run Code Online (Sandbox Code Playgroud)

AppDelegate.m:

@implementation AppDelegate_Pad
@synthesize window;
@synthesize tabBarController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    LoginViewController_Pad *lvc = [[LoginViewController_Pad alloc] initWithNibName:@"LoginViewController_Pad" bundle:nil];
    lvc.delegate = self;
    [window addSubview:lvc.view];
    //[lvc release];
    [window makeKeyAndVisible];
    return YES;
}
- (void)loginViewControllerDidFinish:(LoginViewController_Pad *)loginViewController {
    [window addSubview:tabBarController.view];
}
- (void)dealloc {...}
@end
Run Code Online (Sandbox Code Playgroud)

LoginViewController_Pad.h:

@protocol LoginViewControllerDelegate;
@interface LoginViewController_Pad : UIViewController {
    id<LoginViewControllerDelegate> delegate;
}
@property (nonatomic, assign) id <LoginViewControllerDelegate> delegate;
- (IBAction)buttonPressed;
@end
@protocol LoginViewControllerDelegate
-(void)loginViewControllerDidFinish:(LoginViewController_Pad *)loginViewController;
@end
Run Code Online (Sandbox Code Playgroud)

LoginViewController_Pad.m:

@implementation LoginViewController_Pad
@synthesize delegate;
    ...
- (IBAction)buttonPressed
{
    [self.view removeFromSuperview];
    [self.delegate loginViewControllerDidFinish:self];
}
    ...
@end
Run Code Online (Sandbox Code Playgroud)

因此,app delegate在启动时添加登录视图控制器的视图,并等待登录使用委托调用"done finish".登录视图控制器在调用didFinish之前调用removeFromSuperView.然后,app委托在选项卡栏控制器的视图上调用addSubView.

如果你做到了这一点,谢谢,我有三个问题:

  1. 主要问题:这是在显示应用程序主标签栏控制器之前显示视图控制器的正确方法吗?即使它似乎有用,它是一种正确的方法吗?

  2. 如果我在应用程序委托中注释掉"lvc release",那么当按下登录视图控制器上的按钮时,应用程序将与EXC_BAD_ACCESS崩溃.为什么?

  3. 随着"lvc release"被注释掉,一切似乎都有效,但是在调试器控制台上,当app委托为标签栏控制器调用addSubView时,它会写入此消息:使用两阶段旋转动画.要使用更平滑的单阶段动画,此应用程序必须删除两阶段方法实现. 这是什么意思,我需要担心吗?

更新: 正如lucius所建议的那样,将其更改为从app delegate模态显示登录视图控制器.这似乎是一个更清洁的解决方案.代码更改如下......

AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [window addSubview:tabBarController.view];
    [window makeKeyAndVisible];

    LoginViewController_Pad *lvc = [[LoginViewController_Pad alloc] initWithNibName:@"LoginViewController_Pad" bundle:nil];
    lvc.delegate = self;
    [self.tabBarController presentModalViewController:lvc animated:NO];
    [lvc release];

    return YES;
}
-(void)loginViewControllerDidFinish:(LoginViewController_Pad *)loginViewController {
    [self.mainTabBarController dismissModalViewControllerAnimated:NO];
}
Run Code Online (Sandbox Code Playgroud)

LoginViewController_Pad.m:

- (IBAction)buttonPressed
{
    //do NOT removeFromSuperview, delegate will dismiss
    //[self.view removeFromSuperview];
    [self.delegate loginViewControllerDidFinish:self];
}
Run Code Online (Sandbox Code Playgroud)

luc*_*ius 3

我会使用该方法以模态方式呈现视图控制器,而不是将其添加到窗口中。这将使其正确保留控制器。调试器消息与类中实现的某些自动旋转方法有关。您现在可以忽略它。