添加UINavbarController& TabbarControlller到非根视图

时间:2011-10-20 09:26:15

标签: iphone objective-c ios

我的项目是一个基于视图的项目。

因此,应用代表按正常情况启动。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

然后调用我的第一个viewcontroller并显示两个UITextField,这样用户就可以输入他们的凭据并登录。

当成功时,我调用另一个视图控制器,在其中我向视图添加UINavigationController和UITabBarController。如下所示。

- (void)viewDidLoad
{
[super viewDidLoad];

UINavigationController *localNavigationController;
tabBarController = [[UITabBarController alloc] init];
NSMutableArray *localControllersArray = [[NSMutableArray alloc] initWithCapacity:2];


Hello *firstViewController;
firstViewController = [[Hello alloc] init];
localNavigationController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
[localNavigationController.tabBarItem initWithTitle:@"Test" image:[UIImage imageNamed:@"tabBarIcon.png"] tag:1];
//[localNavigationController.tabBarItem initWithTabBarSystemItem:UITabBarSystemItemDownloads tag:1];
firstViewController.navigationItem.title=@"New Requests";

[localControllersArray addObject:localNavigationController];
[localNavigationController release];
[firstViewController release];


Test *secondViewController;
secondViewController = [[Test alloc] init];
localNavigationController = [[UINavigationController alloc] initWithRootViewController:secondViewController];
[localNavigationController.tabBarItem initWithTitle:@"Test" image:[UIImage imageNamed:@"tabBarIcon.png"] tag:2];
secondViewController.navigationItem.title=@"Existing";


[localControllersArray addObject:localNavigationController];
[localNavigationController release];
[secondViewController release];


// load up our tab bar controller with the view controllers
tabBarController.viewControllers = localControllersArray;

// release the array because the tab bar controller now has it
[localControllersArray release];


// add the tabBarController as a subview in the window
[self.view addSubview:tabBarController.view];

}

到目前为止,这似乎工作正常。 Navbar和Tabbar都被状态栏的高度降低到了一个问题,但是一旦我隐藏了状态栏,就会出现问题。

我有什么理由不这样做吗?这是不好的做法,还是会遇到一些问题?

我可以从app delegate设置Navbar和Tabbar,并在登录屏幕上隐藏它们。这是我看到的唯一其他选择。

我感谢你们提供的任何反馈。到目前为止,我对我所做的结果感到紧张,期待它可能在我脸上爆炸。

非常感谢, -code

2 个答案:

答案 0 :(得分:0)

尝试设置* tabBarController 的框架。

[tabBarController.view setFrame:self.view.bounds];

// add the tabBarController as a subview in the window
[self.view addSubview:tabBarController.view];

答案 1 :(得分:0)

您通常不应直接将UINavigationControllerUITabBarController的视图添加为您自己的视图控制器的子视图。除非你使用新的iOS 5 API,否则这种“视图控制器包含”很难实现。

原因是实际的视图控制器不会收到某些重要消息,如viewDidAppear:和轮换消息。您会注意到奇怪的旋转错误和其他奇怪的问题。你可以自己从父视图控制器转发这些方法,但是在你的情况下你不需要这样做,因为你只是想显示一个标准的标签栏控制器。

通常,您应该将一个视图控制器设置为UIWindow的根视图控制器。这通常是UINavigationControllerUITabBarController等。父UIWindow会将轮换事件和其他消息发送到此控制器。像UITabBarController这样的标准“容器”控制器会将这些消息转发给他们的孩子,以便一切正常。

如果我是你,我总是将标签栏控制器作为窗口的根视图控制器。当您的应用启动时(即在application:didFinishLaunchingWithOptions:中),创建一个空的标签栏控制器并将其设置为根视图控制器:

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // create a basic empty tab bar controller
    self.tabBarController = [[[UITabBarController alloc] init] autorelease];
    // ...

    // Set up the window's root view controller
    self.window.rootViewController = tabBarController;

   // ...
}

现在,每当你在屏幕上显示内容时,它应该是根视图控制器的子代,在你的情况下是标签栏控制器。

因此,一旦设置了根视图控制器,您就可以检查用户是否已经登录。如果是,您可以设置导航控制器和选项卡项,并将它们添加到选项卡栏控制器。

如果用户未登录,您可以使用presentModalViewController:animated:在标签栏控制器的顶部显示登录视图控制器:

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // ...

    // Set up the window's root view controller
    self.window.rootViewController = tabBarController;

    if (isUserLoggedIn()) {
        [self setupTabsAndStuff];

    } else {
        LoginViewController *loginVC = [[[LoginViewController alloc] init] autorelease];
        [self.tabBarController presentModalViewController:loginVC animated:NO];
    }

    // ...
}

animated:NO会在启动应用程序后立即显示登录屏幕,而不会显示动画。

用户输入正确的详细信息后,您可以再次调用setupTabsAndStuff方法并再次关闭登录视图控制器。

总结一下:

  • 您可以直接使用标签栏控制器,而不是将自己的UIViewController放入标签栏控制器的视图中。
  • 将标签栏控制器安装为窗口的根视图控制器。然后,标签栏控制器将正确地将旋转事件和其他特殊消息转发到它包含的视图控制器。
  • 始终将视图和视图控制器作为根视图控制器的子项呈现。如果您需要使用全屏显示内容presentModelViewController:animated