简体   繁体   English

Xcode 如何加载主故事板?

[英]How does Xcode load the main storyboard?

When I create a new single view application in Xcode 4.6 using storyboard, we can see that the main function creates a new application using the application delegate like this:当我使用 storyboard 在 Xcode 4.6 中创建一个新的单视图应用程序时,我们可以看到 main 函数使用应用程序委托创建了一个新应用程序,如下所示:

return UIApplicationMain(argc, argv, nil, NSStringFromClass([MyAppDelegate class]));

However if we look at MyAppDelegate.h and MyAppDelegate.m, there is nowhere in the code that references MainStoryboard.storyboard.然而,如果我们查看 MyAppDelegate.h 和 MyAppDelegate.m,代码中没有任何地方引用 MainStoryboard.storyboard。 This differs from a non-storyboard version where we can find the line of code that loads the nib file programmatically.这与非故事板版本不同,在非故事板版本中,我们可以找到以编程方式加载 nib 文件的代码行。

So my question is, how does the storyboard get loaded?所以我的问题是,故事板是如何加载的? (where should I poke to find it?) (我应该戳哪里才能找到它?)

Look at your Target settings for the Project查看项目的目标设置

在此处输入图片说明

Notice the Main Storyboard setting.注意主故事板设置。

If you wanted to do this in code yourself, you would do something like.如果你想自己在代码中做到这一点,你会做类似的事情。

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

   UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:[NSBundle mainBundle]];
   UIViewController *vc = [storyboard instantiateInitialViewController];

   // Set root view controller and make windows visible
   self.window.rootViewController = vc;
   [self.window makeKeyAndVisible];

   return YES;
}

Give a look to the UIApplicationMain discussion:看看UIApplicationMain 的讨论:

Discussion讨论
This function instantiates the application object from the principal class and instantiates the delegate (if any) from the given class and sets the delegate for the application.此函数从主体类实例化应用程序对象,并从给定类实例化委托(如果有),并为应用程序设置委托。 It also sets up the main event loop, including the application's run loop, and begins processing events.它还设置主事件循环,包括应用程序的运行循环,并开始处理事件。 If the application's Info.plist file specifies a main nib file to be loaded, by including the NSMainNibFile key and a valid nib file name for the value, this function loads that nib file.如果应用程序的 Info.plist 文件通过包含 NSMainNibFile 键和值的有效 nib 文件名指定要加载的主 nib 文件,则此函数加载该 nib 文件。

When UIApplicationMain gets called, a plist file containing all the application info is loaded:UIApplicationMain被调用时,会加载一个包含所有应用程序信息的 plist 文件:

在此处输入图片说明

That's how it "understands" that the xib/storyboard file needs to get loaded.这就是它“理解”需要加载 xib/storyboard 文件的方式。

It is started from the UIMainStoryboardFile setting from your info.plist file.它从 info.plist 文件的 UIMainStoryboardFile 设置开始。 Xcode then creates a main window, instantiates your first view controller, and adds it to the window.然后 Xcode 创建一个主窗口,实例化您的第一个视图控制器,并将其添加到窗口中。 You can still do this in code similar to the .nib using您仍然可以在类似于 .nib 的代码中使用

UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController* initialView = [storyboard instantiateInitialViewController];

In Xcode, the human-readable Info.plist section that determines the main storyboard is:在 Xcode 中,确定主故事板的人类可读的 Info.plist 部分是:

Main storyboard file base name

In plain text, the key is UIMainStoryboardFile :在纯文本中,关键是UIMainStoryboardFile

<key>UIMainStoryboardFile</key>
<string>Main</string>

If you want to instantiate with Swift如果你想用 Swift 实例化

var storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
var vc : AnyObject! = storyboard.instantiateInitialViewController()
self.window!.rootViewController = vc as UIViewController
self.window!.makeKeyAndVisible()

In Xcode 11.3.1, changing Main storyboard file base name alone is not enough, there's a Storyboard Name configuration in the Application Scene Manifest that should also be changed as well.在 Xcode 11.3.1 中,仅更改Main storyboard 文件基本名称是不够的, Application Scene Manifest中的Storyboard Name配置也应该更改。

    <key>UIApplicationSceneManifest</key>
    <dict>
        <key>UIApplicationSupportsMultipleScenes</key>
        <false/>
        <key>UISceneConfigurations</key>
        <dict>
            <key>UIWindowSceneSessionRoleApplication</key>
            <array>
                <dict>
                    <key>UISceneConfigurationName</key>
                    <string>Default Configuration</string>
                    <key>UISceneDelegateClassName</key>
                    <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
                    <key>UISceneStoryboardFile</key>
                    <string>Home</string>
                </dict>
            </array>
        </dict>
    </dict>

Bit late to the party but you can get to the viewController from the window as shown below聚会有点晚,但您可以从窗口进入 viewController,如下所示

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

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

        var viewController = window?.rootViewController as? ViewController
        if let viewController = viewController {
            // do awesome stuff
        }

        return true
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM