【问题标题】:How does Xcode load the main storyboard?Xcode 如何加载主情节提要?
【发布时间】:2013-05-22 22:26:14
【问题描述】:

当我在 Xcode 4.6 中使用 storyboard 创建一个新的单视图应用程序时,我们可以看到 main 函数使用应用程序委托创建了一个新应用程序,如下所示:

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

但是,如果我们查看 MyAppDelegate.h 和 MyAppDelegate.m,代码中没有任何地方引用 MainStoryboard.storyboard。这与非故事板版本不同,我们可以在其中找到以编程方式加载 nib 文件的代码行。

所以我的问题是,故事板是如何加载的? (我应该在哪里找到它?)

【问题讨论】:

    标签: ios objective-c xcode


    【解决方案1】:

    查看项目的目标设置

    注意主情节提要设置。

    如果您想自己在代码中执行此操作,您可以执行类似的操作。

    - (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;
    }
    

    【讨论】:

    • 您需要在self.window.rootViewController = vc;之前添加self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
    【解决方案2】:

    看看 UIApplicationMain 讨论:

    讨论
    此函数从主体类实例化应用程序对象并从给定类实例化委托(如果有)并为应用程序设置委托。它还设置主事件循环,包括应用程序的运行循环,并开始处理事件。如果应用程序的 Info.plist 文件指定要加载的主 nib 文件,通过包含 NSMainNibFile 键和值的有效 nib 文件名,此函数会加载该 nib 文件。

    UIApplicationMain 被调用时,会加载一个包含所有应用程序信息的 plist 文件:

    这就是它“理解”需要加载 xib/storyboard 文件的方式。

    【讨论】:

      【解决方案3】:

      它从 info.plist 文件中的 UIMainStoryboardFile 设置开始。然后 Xcode 创建一个主窗口,实例化您的第一个视图控制器,并将其添加到窗口中。您仍然可以使用

      在类似于 .nib 的代码中执行此操作
      UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
      UIViewController* initialView = [storyboard instantiateInitialViewController];
      

      【讨论】:

        【解决方案4】:

        在 Xcode 中,决定主故事板的人类可读的 Info.plist 部分是:

        Main storyboard file base name

        在纯文本中,密钥是UIMainStoryboardFile

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

        【讨论】:

          【解决方案5】:

          如果你想用 Swift 实例化

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

          【讨论】:

          • 如果要在AppDelegate 中的applicationDidFinishLoading 方法中初始化情节提要,还必须创建window 对象。例如像这样window = UIWindow(frame: UIScreen.mainScreen().bounds)
          • 你应该使用 let 而不是 var 并使用 ?代替 ! (即使你确定),也没有真正的惩罚
          【解决方案6】:

          在 Xcode 11.3.1 中,仅更改 主故事板文件基础名称 是不够的,应用程序场景清单中有一个 故事板名称 配置> 这也应该改变。

              <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>
          

          【讨论】:

          • 在中断了 iOS 开发之后,我完全错过了 UIScene 的东西。这条评论帮助我恢复了理智的单元测试。
          【解决方案7】:

          聚会有点晚了,但您可以从窗口进入 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
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-03-24
            • 2012-10-19
            • 2013-05-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多