使用UINavigationController以编程方式设置RootViewController

6

我有一个带有导航控制器和默认根视图控制器的程序。如果我不进行任何编程操作,应用程序启动并且根视图控制器按照下面的故事板所示按照我预期工作:

enter image description here

我的问题是,通过合并可选的开始视图控制器,我的要求是:在我的AppDelegate(didFinishLaunchingWithOptions)中,我想要像这样的代码:

UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"OptionalStartViewController"];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];

首先展示Optional Start ViewController。然后,当用户完成了Optional ViewController的操作后,可以展示RootViewController。

所以,在Optional Start ViewController中,我添加了以下代码来显示Root View Controller:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"RootViewController"];
[self appDelegate].window.rootViewController = viewController;
[[self appDelegate].window makeKeyAndVisible];

除了RootViewController,其他都正常,当显示时,它没有预期的导航控件(即在没有导航控件的情况下显示视图)。

我还尝试了下面的代码(使用UINavigationController而不是ViewController),但结果相同...

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
UINavigationController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"HomeViewController"];
[self appDelegate].window.rootViewController = viewController;
[[self appDelegate].window makeKeyAndVisible];

还有一个小问题......可能会有多个可选的起始视图控制器。

有什么想法吗?


所以问题是导航栏不见了? - gabbler
使用UINavigationController的标识符代替UIViewController(根视图控制器)。 - n00bProgrammer
将UINavigationController设置为根视图控制器对我来说起作用了。 - gabbler
@gabbler... 你是不是先将另一个视图控制器设置为根视图控制器,然后稍后再显示你的实际根视图控制器?你的代码是什么样子的? - Adam
在我的故事板中,我将可选的视图控制器设置为根视图控制器,在这个可选的视图控制器中,我点击了一个按钮来显示导航控制器,它起作用了。 - gabbler
显示剩余2条评论
3个回答

6
  1. 删除UINavigationController
  2. 选择控制器(在我们的情况下为“可选起始视图控制器”)
  3. 点击Editor >> Embed In >> Navigation Controller
  4. 现在选择Navigation Controller和右侧Utility区域,选择选项Is Initial View Controller

如果要动态更改根视图控制器,则最好以程序方式进行。在 didFinishLaunchingWithOptions 中获取窗口实例,使用根视图控制器初始化导航控制器,然后将窗口的根视图控制器设置为导航控制器。以下是代码示例。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.

    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

    OptionalFirstViewController *optionalFirstViewController = [[OptionalFirstViewController alloc] initWithNibName:@"OptionalFirstViewController" bundle:nil];
    UINavigationController *homeNavigationController = [[UINavigationController alloc] initWithRootViewController:optionalFirstViewController];
    [optionalFirstViewController release];
    self.window.rootViewController = homeNavigationController;
    [homeNavigationController release];
    [self.window makeKeyAndVisible];

    return YES;
}

请确保在story board中取消所有视图控制器的“Is Initial View Controller”复选框。
希望这有所帮助。

如果有多个可选的启动视图控制器怎么办? - Adam
那么,您只需要事先决定要显示哪一个,并使用它。这将在上述代码中增加您的业务规则的复杂性。 - bedranfleck
当然,您需要事先知道根据业务逻辑要显示哪个控制器,您可以将业务逻辑保留在单独的类/方法中,该类/方法返回一个类名,在此处您可以初始化所需的控制器。这只是在上面的代码中添加了一行。 - Saif

2

如果不使用故事板,我们可以在 AppDelegate 类中通过编程方式进行设置。只需在 AppDelegate 中编写下面的几行代码即可。

AppDelegate.h

@property (strong, nonatomic) UIStoryboard *storyboard;
@property (strong, nonatomic) UINavigationController *navigationController;

AppDelegate.m

if(self.window == nil)
    self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];

if(self.navigationController == nil)
    self.navigationController = [[UINavigationController alloc]init];

if(self.storyboard == nil)
    self.storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

self.navigationController.navigationBarHidden = YES;

// Here we can check user is login or not also,

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
ViewController *ivc = [storyboard instantiateViewControllerWithIdentifier:@"ViewController"];
[self.navigationController pushViewController:ivc animated:YES];
self.window.rootViewController = ivc;


[self.window setRootViewController:self.navigationController];
[self.window makeKeyAndVisible];

Swift 版本中,
var window: UIWindow?
var storyBoard :UIStoryboard?
var navigationController : UINavigationController?
var mainController :MainViewController = MainViewController()

if window == nil {
        window = UIWindow(frame: UIScreen.main.bounds)
    }
    if navigationController == nil {
        navigationController = UINavigationController()
    }
    if storyBoard == nil {
        storyBoard = UIStoryboard(name: "Main", bundle:nil)
    }
    navigationController?.setNavigationBarHidden(true, animated: true)
    // storyboard with identifer
    mainController = storyBoard?.instantiateViewController(withIdentifier: "MainViewController") as! MainViewController
    navigationController?.pushViewController(mainController , animated: true)

    window?.rootViewController = navigationController
    window?.makeKeyAndVisible()

1

在初始化后,您无法将新的根视图控制器设置为UINavigationController。您应该根据需要修改UINavigationControllerviewControllers数组。

如果您希望可选的VC成为根VC,请创建@[optionalVC]并将其设置为UINavigationControllerviewControllers数组。


你怎么做到的?navigationController.viewControllers = [optionalVC, secondVC, thirdVC] 像这样吗? - daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接