以编程方式使用 UINavigationController 设置 RootViewController
Posted
技术标签:
【中文标题】以编程方式使用 UINavigationController 设置 RootViewController【英文标题】:Setting a RootViewController with UINavigationController Programmatically 【发布时间】:2015-02-11 15:11:52 【问题描述】:我有一个带有导航控制器和默认 RootViewController 的程序。如果我不以编程方式执行任何操作,应用程序就会启动并且 RootViewController 会按我的预期工作,例如下面的情节提要:
我遇到的问题是通过合并可选的 Start ViewController。我想要的是:在我的 AppDelegate (didFinishLaunchingWithOptions) 中,我想要这样的代码:
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"OptionalStartViewController"];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
首先显示可选的启动 ViewController。然后,在用户完成了 Optional viewcontroller 之后,他们就可以显示 RootViewController。
所以在 Optional Start ViewController 中,我添加了这样的代码来显示根视图控制器:
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];
另一个转折……可能有几个可选的开始视图控制器。
有什么想法吗?
【问题讨论】:
那么问题是导航栏不存在? 使用UINavigationController
的标识符而不是UIViewController
(根视图控制器)。
将 UINavigationController 设置为 root 确实对我有用。
@gabbler...你是不是先设置了一个不同的viewcontroller作为rootviewcontroller,然后再显示你实际的rootviewcontroller?你的代码是什么样的?
在我的故事板中,我将可选的视图控制器设置为根,在这个可选的视图控制器中,我单击了一个按钮来显示导航控制器,它起作用了。
【参考方案1】:
-
删除
UINavigationController
选择控制器(在我们的例子中是“可选的启动视图控制器”)
点击Editor >> Embed In >> Navigation Controller
现在选择Navigation Controller
和右侧实用程序区域,选择选项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;
并确保为故事板中的所有视图控制器取消选中 Is Initial View Controller
希望对你有帮助
【讨论】:
如果有多个可选的启动视图控制器怎么办? 好吧,那么您只需要事先决定要显示哪个并使用它。这增加了上述代码的业务规则的复杂性。 是的,当然你需要事先知道根据你的业务逻辑显示哪个控制器,你总是可以将业务逻辑保存在一个单独的类/方法中,它返回一个类名,在这里你可以初始化所需的控制器。这只是在上面的代码中增加了一行。【参考方案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()
【讨论】:
【参考方案3】:初始化后,您不能将新的根视图控制器设置为UINavigationController
。您应该根据需要修改UINavigationController
的viewControllers
数组。
如果您希望可选 VC 为根 VC,请创建 @[optionalVC]
并将其设置为 UINavigationController
的 viewControllers
数组。
【讨论】:
以上是关于以编程方式使用 UINavigationController 设置 RootViewController的主要内容,如果未能解决你的问题,请参考以下文章