如何在不使用情节串连板的情况下创建一个新的 Swift 项目?

在 XCode6中创建新项目不允许禁用情节串连板。您只能选择 Swift 或 Objective-C,并使用或不使用核心数据。

我尝试删除故事板,并从项目中删除主要的故事板,并手动设置窗口从 did FinishLaunching

在应用代表中我有这个:

class AppDelegate: UIResponder, UIApplicationDelegate {


var window: UIWindow
var testNavigationController: UINavigationController


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {


testNavigationController = UINavigationController()
var testViewController: UIViewController = UIViewController()
self.testNavigationController.pushViewController(testViewController, animated: false)


self.window = UIWindow(frame: UIScreen.mainScreen().bounds)


self.window.rootViewController = testNavigationController


self.window.backgroundColor = UIColor.whiteColor()


self.window.makeKeyAndVisible()


return true
}
}

然而,XCode 给了我一个错误:

类“ AppDelegate”没有初始值设定项

有人成功过吗?

69219 次浏览

You must mark the window and testNavigationController variables as optional:

var window : UIWindow?
var testNavigationController : UINavigationController?

Swift classes require non-optional properties to be initialized during the instantiation:

Classes and structures must set all of their stored properties to an appropriate initial value by the time an instance of that class or structure is created. Stored properties cannot be left in an indeterminate state.

Properties of optional type are automatically initialized with a value of nil, indicating that the property is deliberately intended to have “no value yet” during initialization.

When using optional variables, remember to unwrap them with !, such as:

self.window!.backgroundColor = UIColor.whiteColor();

I have found the answer it had nothing to do with the xcode setup, removing storyboard and the reference from project is the right thing. It had to do with the swift syntax.

The code is the following:

class AppDelegate: UIResponder, UIApplicationDelegate {


var window: UIWindow?
var testNavigationController: UINavigationController?


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {


self.testNavigationController = UINavigationController()
var testViewController: UIViewController? = UIViewController()
testViewController!.view.backgroundColor = UIColor.redColor()
self.testNavigationController!.pushViewController(testViewController, animated: false)


self.window = UIWindow(frame: UIScreen.mainScreen().bounds)


self.window!.rootViewController = testNavigationController


self.window!.backgroundColor = UIColor.whiteColor()
self.window!.makeKeyAndVisible()


return true
}


}

Try the following code:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window!.backgroundColor = UIColor.whiteColor()


// Create a nav/vc pair using the custom ViewController class


let nav = UINavigationController()
let vc = NextViewController ( nibName:"NextViewController", bundle: nil)


// Push the vc onto the nav
nav.pushViewController(vc, animated: false)


// Set the window’s root view controller
self.window!.rootViewController = nav


// Present the window
self.window!.makeKeyAndVisible()
return true


}

You can just do it like this:

class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var IndexNavigationController: UINavigationController?


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
var IndexViewContoller : IndexViewController? = IndexViewController()
self.IndexNavigationController = UINavigationController(rootViewController:IndexViewContoller)
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window!.rootViewController = self.IndexNavigationController
self.window!.backgroundColor = UIColor.whiteColor()
self.window!.makeKeyAndVisible()
return true
}
}

I recommend you use controller and xib

MyViewController.swift and MyViewController.xib

(You can create through File->New->File->Cocoa Touch Class and set "also create XIB file" true, sub class of UIViewController)

class MyViewController: UIViewController {
.....
}

and In AppDelegate.swift func application write the following code

....
var controller: MyViewController = MyViewController(nibName:"MyViewController",bundle:nil)
self.window!.rootViewController = controller
return true

It should be work!

Why don't you just create an empty application? the storyboard is not created to me...

We can create navigation-based application without storyboard in Xcode 6 (iOS 8) like as follows:

  • Create an empty application by selecting the project language as Swift.

  • Add new cocoa touch class files with the interface xib. (eg. TestViewController)

  • In the swift we have only one file interact with the xib i.e. *.swift file, there is no .h and .m files.

  • We can connect the controls of xib with swift file same as in iOS 7.

Following are some snippets for work with the controls and Swift

//
//  TestViewController.swift
//


import UIKit


class TestViewController: UIViewController {


@IBOutlet var testBtn : UIButton


init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
// Custom initialization
}


@IBAction func testActionOnBtn(sender : UIButton) {
let cancelButtonTitle = NSLocalizedString("OK", comment: "")


let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .Alert)


// Create the action.
let cancelAction = UIAlertAction(title: cancelButtonTitle, style: .Cancel) { action in
NSLog("The simple alert's cancel action occured.")
}


// Add the action.
alertController.addAction(cancelAction)


presentViewController(alertController, animated: true, completion: nil)
}


override func viewDidLoad() {
super.viewDidLoad()
}


override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}


}

Changes in AppDelegate.swift file

//
//  AppDelegate.swift
//


import UIKit


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {


var window: UIWindow?


var navigationController: UINavigationController?


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window!.backgroundColor = UIColor.whiteColor()
self.window!.makeKeyAndVisible()


var testController: TestViewController? = TestViewController(nibName: "TestViewController", bundle: nil)
self.navigationController = UINavigationController(rootViewController: testController)
self.window!.rootViewController = self.navigationController


return true
}


func applicationWillResignActive(application: UIApplication) {
}


func applicationDidEnterBackground(application: UIApplication) {
}


func applicationWillEnterForeground(application: UIApplication) {
}


func applicationDidBecomeActive(application: UIApplication) {
}


func applicationWillTerminate(application: UIApplication) {
}


}

Find code sample and other information on http://ashishkakkad.wordpress.com/2014/06/16/create-a-application-in-xcode-6-ios-8-without-storyborard-in-swift-language-and-work-with-controls/

All it takes for not using Storyboards for the rootViewController:

1· Change AppDelegate.swift to:

import UIKit


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {


var window: UIWindow?


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

2· Create a ViewController subclass of UIViewController:

import UIKit


class ViewController: UIViewController {


override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.blue
}
}

3· If you created the project from an Xcode template:

  1. Remove the key-value pair for key "Main storyboard file base name" from Info.plist.
  2. Delete the storyboard file Main.storyboard.

As you can see in the first code snippet, instead of implicitly unwrapping an optional, I rather like the if let syntax for unwrapping the optional window property. Here I'm using it like if let a = a { } so that the optional a becomes a non-optional reference inside the if-statement with the same name – a.

Finally self. is not necessary when referencing the window property inside it own class.

If you want to Initialize your viewController with xib and and need to use navigation controller. Here is a piece of code.

var window: UIWindow?
var navController:UINavigationController?
var viewController:ViewController?


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window = UIWindow(frame: UIScreen.mainScreen().bounds)


viewController = ViewController(nibName: "ViewController", bundle: nil);
navController = UINavigationController(rootViewController: viewController!);


window?.rootViewController = navController;
window?.makeKeyAndVisible()


return true
}

Here is a complete swift test example for an UINavigationController

        import UIKit
@UIApplicationMain
class KSZAppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var testNavigationController: UINavigationController?


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
// Working WITHOUT Storyboard
// see http://randexdev.com/2014/07/uicollectionview/
// see http://stackoverflow.com/questions/24046898/how-do-i-create-a-new-swift-project-without-using-storyboards
window = UIWindow(frame: UIScreen.mainScreen().bounds)
if let win = window {
win.opaque = true
//you could create the navigation controller in the applicationDidFinishLaunching: method of your application delegate.
var testViewController: UIViewController = UIViewController()
testNavigationController = UINavigationController(rootViewController: testViewController)
win.rootViewController = testNavigationController
win.backgroundColor = UIColor.whiteColor()
win.makeKeyAndVisible()
// see corresponding Obj-C in https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/NavigationControllers.html#//apple_ref/doc/uid/TP40011313-CH2-SW1
//      - (void)applicationDidFinishLaunching:(UIApplication *)application {
//    UIViewController *myViewController = [[MyViewController alloc] init];
//    navigationController = [[UINavigationController alloc]
//                                initWithRootViewController:myViewController];
//    window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
//    window.rootViewController = navigationController;
//    [window makeKeyAndVisible];
//}
}
return true
}
}

Updated for Swift 3.0:

window = UIWindow()
window?.rootViewController = ViewController()
window?.makeKeyAndVisible()

Update: Swift 5 and iOS 13:

  1. Create a Single View Application.
  2. Delete Main.storyboard (right-click and delete).
  3. Delete Storyboard Name from the default scene configuration in the Info.plist file: enter image description here
  4. Open SceneDelegate.swift and change func scene from:
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 }
}

to

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

In iOS 13 and above when you create new project without storyboard use below steps:

  1. Create project using Xcode 11 or above
  2. Delete storyboard nib and class
  3. Add new new file with xib
  4. Need to set root view as UINavigationController SceneDelegate
  5. add below code:
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 }
    

if let windowScene = scene as? UIWindowScene {
self.window = UIWindow(windowScene: windowScene)
let mainController = HomeViewController() as HomeViewController
let navigationController = UINavigationController(rootViewController: mainController)
self.window!.rootViewController = navigationController
self.window!.makeKeyAndVisible()
}
}