UIStoryBoard 从 ApplicationDelegate 获取第一个视图控制器

Posted

技术标签:

【中文标题】UIStoryBoard 从 ApplicationDelegate 获取第一个视图控制器【英文标题】:UIStoryBoard get first view controller from ApplicationDelegate 【发布时间】:2011-12-22 22:32:53 【问题描述】:

我有一个我的 ApplicationDelegate 实现的协议。我想将此传递给故事板中定义的第一个视图控制器。如何从方法中访问它?

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

【问题讨论】:

【参考方案1】:

我不确定我是否正确理解了这个问题,我认为您是在问如何在情节提要中获得第一个 viewController。要得到这个,你打电话,

UIStoryboard *storybord = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc =[storybord instantiateInitialViewController];

更改故事板的名称以适合您的名称,MainStoryboard 只是默认名称。希望这就是您想要的。

编辑:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

    UIStoryboard *storybord = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    UIViewController *vc =[storybord instantiateInitialViewController];
    //set the delegate on the view controller that you have loaded
    // Override point for customization after application launch.
    return YES;

【讨论】:

是的,这就是我需要的。关于如何在通用应用程序(iphone vs ipad)中为设备加载正确的故事板有什么想法吗? 应该这样做UIViewController *vc; if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) UIStoryboard *storybord = [UIStoryboard storyboardWithName:@"MainiPadStoryboard" bundle:nil]; vc = [storybord instantiateInitialViewController]; else UIStoryboard *storybord = [UIStoryboard storyboardWithName:@"MainiPhoneStoryboard" bundle:nil]; vc = [storybord instantiateInitialViewController]; 很确定这是获取新副本,而不是现有副本。 如果您不想硬编码故事板名称,正如 Scott 指出的那样,iPhone 和 iPad 的名称会有所不同,名称在 info.plist 文件中定义,可以按如下方式提取: NSString *storyBoardName = [[NSBundle mainBundle].infoDictionary objectForKey:@"UIMainStoryboardFile"]; self.storyboard = [UIStoryboard storyboardWithName:storyBoardName bundle:[NSBundle mainBundle]];【参考方案2】:

然后使用

创建现有故事板的新副本
UIStoryboard *storybord = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

你可以在你的应用代理的头文件中设置这个属性

@property (nonatomic, weak) UIViewController* initialViewController;

在这个方法中,只需将 self.window.rootViewController 分配给属性

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

    self.initialViewController = self.window.rootViewController;

    return YES;

这应该可行,因为在应用程序委托协议的窗口属性中可以访问 rootViewConroller,如果使用故事板,则此控制器是 initialViewController。

【讨论】:

这行得通,而且是正确的答案;实例化一个新的控制器与从情节提要中指向已经实例化的控制器是不同的。【参考方案3】:

Swift 2.0 实现,适合那些想要的人。

您可能需要修改 STROYBAORD 和控制器视图标识符。还有哦

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 

        let storyboard: UIStoryboard = UIStoryboard(name: "[STORYBOARD NAME]", bundle: nil)
        let viewController:UIViewController = storyboard.instantiateViewControllerWithIdentifier("[CONTROLLER IDENTIFIER]")   // You have replace UIViewController with you customer controll type


        self.window?.rootViewController = viewController
        self.window?.makeKeyAndVisible()

        return true
    

【讨论】:

尝试理解问题,而不是仅仅将接受的答案转换成 swift... @Martin 我已经编辑了答案。希望现在即使是ios初学者也能理解。 但是您的解决方案创建了一个新的视图控制器,而 @aran 正在寻找一个解决方案来获取现有的第一个视图控制器。当前接受的答案不是一个好的答案。 @Martin 当前接受的答案不是我的答案。它的斯科特舍伍德。如果正确答案不是一个好答案,为什么不添加正确答案而不是评论其他答案。另外,您如何为其他问题提供答案?只有问题 ower (Aran Mulholland) 才能将其标记为正确答案。 Aran Mulholland 将答案标记为正确,因为该解决方案对他有效。 因为正确答案已经在这里(请参阅@PeterStajger 之一)并且是在提出问题 2 年后发布的。也许提问者确实接受了接受的那个,因为当时没有更好的答案。 AranMulholland 在他最初的问题中希望获得第一个视图控制器现有实例。在这种情况下提供一个新创建的没有任何意义。

以上是关于UIStoryBoard 从 ApplicationDelegate 获取第一个视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在不同的 UIStoryBoard 的 UIViewController 中使用 UIStoryBoard?

从 AppDelegate 调用 navigationController

UIStoryboard() 中的 nil 和 NSBundle 有啥区别?

UIStoryBoard 加载 rootController

Xcode - UIStoryboard 黑屏

uistoryboard跳转界面