【问题标题】:How to create an Empty Application in Xcode without Storyboard如何在没有 Storyboard 的 Xcode 中创建一个空应用程序
【发布时间】:2014-11-05 03:45:46
【问题描述】:

Xcode6 在创建新项目时删除了Empty Application 模板。我们如何在Xcode6 及更高版本中创建一个空应用程序(没有故事板),就像在早期版本中一样?

【问题讨论】:

标签: ios xcode storyboard xcode6


【解决方案1】:

XCode6 及以上版本没有直接创建空应用程序的选项,如XCode5 及更早版本。但是我们仍然可以按照以下步骤创建一个没有Storyboard 的应用程序:

  1. 创建Single View Application
  2. 删除 Main.storyboardLaunchScreen.xib(选择它们,右键单击,然后选择 从项目中删除它们,或完全删除它们)。
  3. 删除“主故事板文件基本名称”和“启动屏幕界面 Info.plist 文件中的文件基本名称”条目。
  4. 打开 AppDelegate.m,编辑 applicationDidFinishLaunchingWithOptions 使其如下所示:

Swift 3 及更高版本:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 
    {
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.backgroundColor = UIColor.white
        self.window?.makeKeyAndVisible()
        return true
    }

Swift 2.x:

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 
    {
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        self.window?.backgroundColor = UIColor.whiteColor()
        self.window?.makeKeyAndVisible()
        return true
    }

目标-C:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        // Override point for customization after application launch.
        self.window.rootViewController = [[ViewController alloc] init];
        self.window.backgroundColor = [UIColor whiteColor];
        [self.window makeKeyAndVisible];
        return YES;
    }

【讨论】:

  • 我喜欢保留LaunchScreen.xib 和相应的Info.plist 条目。没有它,应用程序不会在更大的 iPhone 上占据整个屏幕,这很丑。
  • 我自己喜欢保留故事板。创建各种东西很方便,但我需要在不依赖故事板的情况下进行初始设置。
  • 可能是 Xcode 7 中的一个错误,我根本无法从项目信息设置屏幕中删除 Main.storyboard。我使用了@Silentwarrior 提到的 Xcode 5 空应用程序模板。
  • 除非您手动安装根 ViewController,否则此答案会在 XCode7 中生成运行时错误:'NSInternalInconsistencyException',原因:'应用程序窗口应在应用程序启动结束时具有根视图控制器'
  • 请添加此代码:self.window.rootViewController= [[ViewController alloc]init];在您的 AppDelegate.m 中的 didFinishLaunchingWithOptions 方法下。否则你会得到以下错误:'应用程序窗口应该在应用程序启动结束时有一个根视图控制器'
【解决方案2】:

一种简单的方法是将XCode 5Empty Application 模板复制到XCode 的模板目录。

您可以从here下载XCode 5Empty Application模板,然后解压并复制到/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/Project Templates/iOS/Application目录下。

P.S 这种方法也适用于 swift!

编辑
正如@harrisg 在下面的评论中所建议的那样,您可以将上述模板放在~/Library/Developer/Xcode/Templates/Project Templates/iOS/Application/ 文件夹中,这样即使Xcode 更新它也可以使用。
如果不存在这样的目录,那么您可能必须创建此目录结构:Templates/Project Templates/iOS/Application/ in ~/Library/Developer/Xcode/

使用这种简单的方法,我可以在XCode 6 中创建一个Empty Application。 (下面附上截图)

希望这会有所帮助!

【讨论】:

  • 谢谢。请注意,您需要在 Xcode 更新后替换此模板。
  • 如果你把它放到~/Library/Developer/Xcode/Templates/Project Templates/iOS/Application/ 每次Xcode更新都不需要更换
  • @harrisg 在优胜美地找不到这个目录。你能确认它的存在吗?谢谢
  • 这种方法适用于 Xcode 7.1,但是创建的 LaunchScreen.storyboard 可能有些人不想要。我最终使用了它,因为它不会干扰我手动创建的视图。
  • 记得把文件解压到目录下,复制是不行的。
【解决方案3】:

您还需要执行几个步骤:

  1. 添加前缀文件。 (如果需要)
  2. 添加默认启动图像,否则 iPhone 5 上的应用大小将为 320x480。

所以这里有一个完整的教程:

  1. 删除 Main.storyboard 文件
  2. 删除 LaunchScreen.xib 文件
  3. 删除 Info.plist 中的“主故事板文件基本名称”属性
  4. 删除 Info.plist 中的“启动屏幕界面文件基本名称”属性
  5. 将“[app name]-Prefix.pch”文件添加到包含内容的支持文件中:

    #import <Availability.h>
    
    #ifndef __IPHONE_3_0
    #warning "This project uses features only available in iOS SDK 3.0 and later."
    #endif
    
    #ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    #endif
    
  6. 将“$SRCROOT/$PROJECT_NAME/[pch 文件名]”添加到项目设置 -> 构建设置 -> Apple LLVM 6.0 - 语言 -> “前缀标题”

  7. 将“YES”添加到项目设置 -> 构建设置 -> Apple LLVM 6.0 - 语言 -> “预编译前缀标头”
  8. 打开“Image.xcassets”并添加 LaunchImage
  9. 构建项目,然后会有一个关于缺少默认启动图像的警告,只需按下警告并选择添加默认, 这将添加“Default-568h@2x” 或者 - 如果您想使用“Images.xcassets”中的启动图像,请转到项目设置 -> TARGETS -> 常规 -> 在“启动图像源”中选择使用资产目录,它将创建一个新目录,您可以然后选择,将其用作现有资产目录。
  10. 实现application:didFinishLaunchingWithOptions:方法:

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    //Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    
    return YES;
    

【讨论】:

    【解决方案4】:

    Akhils 的回答是完全正确的。对于我们这些使用 Swift 的人来说,应该是这样的:

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        self.window?.backgroundColor = UIColor.whiteColor()
        self.window?.makeKeyAndVisible()
        return true
    }
    

    【讨论】:

      【解决方案5】:

      Xcode 9.3.1Swift 4

      1. 首先,您需要删除 Project navigator 菜单中的 Main.storyboard
      2. 然后删除 Info.plist 中的 Main storyboard file base name 行。
      3. 不要忘记删除 Main Interface 中的单元格(只需删除 Main项目目标 - 常规 - 部署信息
      4. 之后,转到 AppDelegate.swift 并在函数 didFinishLaunchingWithOptions 中编写下一个:

        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            // Override point for customization after application launch.
        
            window = UIWindow(frame: UIScreen.main.bounds)
            window?.makeKeyAndVisible()
            window?.rootViewController = UINavigationController(rootViewController: ViewController())
        
            return true
        }
        

      Xcode 11.2.1Swift 5

      1. 首先,您需要删除 Project navigator 菜单中的 Main.storyboard
      2. 然后删除 Info.plist 中的 Main storyboard file base name 行。
      3. 不要忘记删除 Project Target - General - Deployment Info 中的单元格 Main Interface(只需删除 Main)。。李>
      4. 这一步很重要,以前版本的 Xcode 和 Swift 中没有。在 Info.plist 中转到:Application Scene ManifestScene ConfigurationApplication Session RoleItem 0 并在此处删除 Storyboard.name 行。
      5. 之后,转到 SceneDelegate 并在函数 scene 中编写下一个:

        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
            // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
            // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
            guard let windowScene = (scene as? UIWindowScene) else { return }
        
            window = UIWindow(frame: windowScene.coordinateSpace.bounds)
            window?.windowScene = windowScene
            window?.rootViewController = ViewController()
            window?.makeKeyAndVisible()
        }
        

      【讨论】:

        【解决方案6】:

        更新:Swift 5 和 iOS 13:

        1. 创建单一视图应用程序。
        2. 删除 Main.storyboard(右键单击并删除)。
        3. 从 Info.plist 文件中的默认场景配置中删除“故事板名称”:
        4. 打开SceneDelegate.swift并将func scene从:
        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
            // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
            // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
            guard let _ = (scene as? UIWindowScene) else { return }
        }
        

         func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
            // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
            // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).x
        
            if let windowScene = scene as? UIWindowScene {
                let window = UIWindow(windowScene: windowScene)
                window.rootViewController = ViewController()
                self.window = window
                window.makeKeyAndVisible()
            }
        }
        

        【讨论】:

        • 您还必须从 Info.plist 中删除“主故事板文件基本名称”,否则您将收到错误“找不到名为 'Main' 的故事板”
        【解决方案7】:

        您还需要做一个步骤:

        1) 删除 plist 文件中的主故事板文件基本名称

        //AppDelegate.h
        
        
        @property (strong, nonatomic) UIViewController *viewController;
        @property (strong, nonatomic) UINavigationController *nav;
        
        //AppDelegate.m
        
        - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {`enter code here`
            // Override point for customization after application launch.
        
            CGRect screenBounds = [[UIScreen mainScreen] bounds];
        
            UIWindow *window = [[UIWindow alloc] initWithFrame:screenBounds];
        
        
            self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        
        
        
            self.viewController = [[UIViewController alloc] initWithNibName:@"ViewController" bundle:nil];
        
            self.nav = [[UINavigationController alloc] initWithRootViewController:self.viewController];
        
            [window setRootViewController:  self.nav];
        
            [window makeKeyAndVisible];
        
            [self setWindow:window];
        
            return YES;
        }
        

        【讨论】:

        • 存在边界问题,UIScreen.mainScreen().bounds 正在打印:(0.0,0.0,320.0,480.0)。这是为什么呢?
        【解决方案8】:

        我有在 Xcode 6 之前的 Xcode 版本中使用的原始 Empty Application 模板。我已将其上传到 here

        您可以下载它并手动将其粘贴到 Xcode 模板目录中,也可以使用 Xcode 的包管理器 Alcatraz 安装它。只需搜索 Xcode 空应用程序

        【讨论】:

          【解决方案9】:

          删除 Main.storyboard 文件

          这可以简单地删除。

          更新 ProjectName-Info.plist 文件

          删除Main storyboard base file name 键。

          创建一个 nib 文件并链接到项目的视图控制器

          1.创建一个nib文件(文件->新建->文件->查看)

          2.将File's Owner's 类更新为项目的任何视图 控制器被调用

          3.将File's Owner'sview出口链接到nib文件中的view对象

          更新应用委托

          1.导入项目视图控制器的头文件

          2.更新application:didFinishLaunchingWithOptions:方法:

          - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
              // Override point for customization after application launch.
              self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
              MyViewController *viewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
              self.window.rootViewController = viewController;
              [self.window makeKeyAndVisible];
              return YES;
          }
          

          【讨论】:

            【解决方案10】:

            对于Xcode 8Swift 3 只需删除.storyboard文件,它会自动从您的.plist中删除相应的引用,并在您的AppDelegate.swift中添加以下代码。

                let initialViewController = UIViewController()
                initialViewController.view.backgroundColor = .white
                window = UIWindow(frame: UIScreen.main.bounds)
                window?.rootViewController = initialViewController
                window?.makeKeyAndVisible()
            

            您可以编写自己的自定义 ViewCountroller 并在 AppDelegate.swift 中用作您的 self.window?.rootViewController,只需在上面的代码中将 UIViewController 替换为您自己的 ViewController。

            【讨论】:

            • 使用 Xcode 9.1 和 Swift 4 如果我只是删除情节提要文件而不手动从 .plist 中删除相应的引用,我会收到错误消息“在捆绑包中找不到名为 'Main' 的情节提要”。看来我必须手动删除引用。
            【解决方案11】:

            我正在使用 XCode6 Beta 并且我通过将 Empty 模板从 XCode5.x.x 添加到 XCode6 Beta 来搜索此问题的另一种解决方案。

            为此,在 Applications 中右键单击 XCode5.x.x,单击“Show Package Content”并从给定路径复制“Empty Application.xctemplate”

            Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/Project Templates/Application

            现在退出窗口并打开 XCode6 的给定路径

            Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/Project Templates/iOS/Application/

            将“Empty Application.xctemplate”粘贴到应用程序文件夹中。现在通过退出并创建新项目来重新启动 XCode6。您将获得“空应用程序”选项。

            现在,当我创建新的 Empty 项目时,项目中自动添加了一个 .pch 文件(我们必须在 XCode6 中手动添加)

            希望能成功

            【讨论】:

              【解决方案12】:

              是的,或者只是使用以前的 Beta 之一来创建它,然后继续使用最新版本。

              【讨论】:

                【解决方案13】:

                您可以为 Xcode 创建自己的项目模板。对于您的要求,您可以使用本网站上的模板:

                https://github.com/elprup/xcode7-project-template

                【讨论】:

                  【解决方案14】:

                  其他人已经解释了如何摆脱情节提要,所以我将在此处跳过那个。这就是我更喜欢在我的代码中使用较少可选链接(用 Swift 3.1 编写)的方式:

                  func application(_ application: UIApplication,
                                   didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
                  
                      let window = UIWindow(frame: UIScreen.main.bounds)
                      window.backgroundColor = .white
                      window.rootViewController = MyRootViewController()
                      window.makeKeyAndVisible()
                      self.window = window
                  
                      return true
                  }
                  

                  【讨论】:

                    【解决方案15】:

                    Xcode 11 和 ios 13 更新。设置完所有内容后仍然看到黑屏,这是因为生命周期由 UISceneDelegate 处理,当您创建新项目时,它会自动生成 UISceneDelegate.m 和 UISceneDelegate 。H。回到我们习惯 UISceneDelegate 之前的过去。以下步骤可能会有所帮助:

                    1. 删除 plist 中的应用场景清单。

                    2. 删除 Application Scene Manifest.h 和 Application Scene Manifest.m

                    3. 删除#pragma 标记下的代码 - APPdelegate.m 中的 UISceneSession 生命周期

                    4. 添加@property(强,非原子)UIWindow * 窗口;在 APPdelegate.h

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2014-04-16
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-02-11
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多