Bagaimana cara membuat proyek Swift baru tanpa menggunakan Papan Cerita?


107

Membuat proyek baru di XCode 6 tidak memungkinkan untuk menonaktifkan Storyboards. Anda hanya dapat memilih Swift atau Objective-C dan menggunakan atau tidak Core Data.

Saya mencoba menghapus storyboard dan dari proyek menghapus storyboard utama dan secara manual mengatur jendela dari didFinishLaunching

Di AppDelegate saya punya ini:

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

Namun, XCode memberi saya kesalahan:

Kelas 'AppDelegate' tidak memiliki penginisialisasi

Ada yang berhasil dalam hal ini?


Jawaban:


71

Anda harus menandai variabel windowdan testNavigationControllersebagai opsional:

var window : UIWindow?
var testNavigationController : UINavigationController?

Kelas Swift memerlukan properti non-opsional untuk diinisialisasi selama pembuatan instance:

Kelas dan struktur harus menyetel semua properti yang disimpan ke nilai awal yang sesuai pada saat instance kelas atau struktur tersebut dibuat. Properti yang disimpan tidak dapat dibiarkan dalam keadaan tidak pasti.

Properti tipe opsional secara otomatis diinisialisasi dengan nilai nil, menunjukkan bahwa properti sengaja dimaksudkan untuk memiliki "belum ada nilai" selama inisialisasi.

Saat menggunakan variabel opsional, ingatlah untuk membukanya dengan !, seperti:

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

1
Semuanya masuk akal dalam jawaban Anda, sampai akhir. tolong jelaskan bagian terakhir itu ?? membuka? apakah ini diperlukan?
DanMoore

1
Anda tidak dapat menyimpan properti non-opsional di Anda AppDelegate(kecuali jika memiliki nilai selama inisialisasi, atau diselesaikan dengan malas). Jika Anda menyimpan properti opsional dan Anda yakin tidak nil, Anda "membukanya dari opsionalitas" menggunakan !operator.
akashivskyy

apa praktik terbaiknya, self.window! atau gunakan if let window = ..?
tertawa

1
Jika Anda yakin bahwa jendela Anda ada (dan Anda dapat yakin dalam kasus khusus ini), Anda dapat pergi dengan !.
akashivskyy

jadi apakah ini berarti ketika kita menggunakan storyboard, backgroundColor menjadi default .white?
Madu

91

Semua yang diperlukan untuk tidak menggunakan Papan Cerita untuk rootViewController:

1 · Ubah AppDelegate.swiftke:

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 · Buat ViewControllersubclass dari UIViewController:

import UIKit

class ViewController: UIViewController {

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

3 · Jika Anda membuat proyek dari template Xcode:

  1. Hapus pasangan nilai kunci untuk kunci "Main storyboard file base name"dari Info.plist.
  2. Hapus file storyboard Main.storyboard.

Seperti yang Anda lihat di cuplikan kode pertama, alih-alih secara implisit membuka bungkus opsional, saya lebih suka if letsintaks untuk membuka bungkus windowproperti opsional . Di sini saya menggunakannya if let a = a { }sedemikian rupa sehingga opsional amenjadi referensi non-opsional di dalam if-statement dengan nama yang sama - a.

Akhirnya self.tidak diperlukan saat mereferensikan windowproperti di dalam kelasnya sendiri.


1
Mengapa if let window = window {? Saya menemukan jawabannya! Jadi Anda tidak perlu menggunakan window!setiap saat.
Bilal Akil

@ 2unco Saya senang Anda menemukan jawabannya. Ini dijelaskan di bagian terakhir jawaban saya tentang if let a = a {}.
tobiasdm

Saya akan memindahkan panggilan makeKeyAndVisible()menjadi setelah pengaturan rootViewController. Jika tidak, Anda akan mendapatkan peringatan tentang bagaimana jendela diharapkan memiliki pengontrol tampilan root di akhir peluncuran aplikasi.
Sebastien Martin

if let a = a { }terlihat aneh. Apakah Anda yakin tidak masalah menggunakan nama variabel yang sama untuk referensi non-opsional? Apple selalu menggunakan nama yang berbeda di dokumen Swift mereka. Juga, mengapa ini lebih baik daripada hanya digunakan window!setiap saat?
ma11hew28

1. if let a = a { }baik-baik saja. Anda bisa menggunakannya if let anA = a { }jika itu membuat Anda merasa lebih nyaman. 2. window!adalah pemeriksaan runtime karena Anda secara eksplisit membuka bungkusan opsional. Saya suka pemeriksaan waktu kompilasi yang disediakan Swift kepada kita, jadi mengapa tidak menggunakannya.
tobiasdm

13

Jika Anda ingin menginisialisasi viewController Anda dengan xib dan dan perlu menggunakan pengontrol navigasi. Ini adalah potongan kode.

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
}

6

Coba kode berikut:

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

}

2

Saya telah menemukan jawabannya tidak ada hubungannya dengan pengaturan xcode, menghapus storyboard dan referensi dari proyek adalah hal yang benar. Itu ada hubungannya dengan sintaks cepat.

Kodenya adalah sebagai berikut:

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
    }

}

Tetapi mengapa menjawab pertanyaan Anda sendiri, jika solusinya ada di jawaban lain?
akashivskyy

halaman tidak diperbarui dan saya tidak melihat jawabannya, hanya setelah posting
EhTd

2

Anda bisa melakukannya seperti ini:

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

Apakah var window: UIWindow? tentukan bahwa itu adalah properti opsional?
Sean Dunford

Saya baru saja mencoba menambahkan var kedua di app delegate tanpanya dan ternyata pernyataan saya di atas benar.
Sean Dunford

2

Saya sarankan Anda menggunakan pengontrol dan xib

MyViewController.swift dan MyViewController.xib

(Anda dapat membuat melalui File-> New-> File-> Cocoa Touch Class dan mengatur "juga membuat file XIB" menjadi benar, sub kelas UIViewController)

class MyViewController: UIViewController {
   .....    
}

dan Di AppDelegate.swift func applicationtulis kode berikut

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

Seharusnya itu berhasil!


Saya mencoba cara yang sama yang Anda sebutkan tetapi kesalahan: Menghentikan aplikasi karena pengecualian yang tidak tertangkap 'NSInternalInconsistencyException', alasan: 'Tidak dapat memuat NIB dalam bundel:
shripad20

2

Diperbarui untuk Swift 3.0:

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

2

Pembaruan: Swift 5 dan iOS 13:

  1. Buat Aplikasi Single View.
  2. Hapus Main.storyboard (klik kanan dan hapus).
  3. Hapus Nama Storyboard dari konfigurasi adegan default di Info.plistfile:masukkan deskripsi gambar di sini
  4. Buka SceneDelegate.swiftdan ubah func scenedari:
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 }
}

untuk

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

1

Berikut adalah contoh uji cepat lengkap untuk 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
          }
    }

0

Mengapa Anda tidak membuat aplikasi kosong saja? storyboard tidak dibuat untuk saya ...


0

Kita bisa membuat aplikasi berbasis navigasi tanpa storyboard di Xcode 6 (iOS 8) seperti berikut:

  • Buat aplikasi kosong dengan memilih bahasa proyek sebagai Swift.

  • Tambahkan file kelas cocoa touch baru dengan antarmuka xib. (mis. TestViewController)

  • Dalam swift kita hanya memiliki satu file yang berinteraksi dengan file xib yaitu * .swift, tidak ada file .h dan .m.

  • Kami dapat menghubungkan kontrol xib dengan file swift yang sama seperti di iOS 7.

Berikut adalah beberapa cuplikan untuk bekerja dengan kontrol dan 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()
    }

}

Perubahan pada file AppDelegate.swift

//
//  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) {
    }

}

Temukan contoh kode dan informasi lainnya di http://ashishkakkad.wordpress.com/2014/06/16/create-a-application-in-xcode-6-ios-8-without-storyborard-in-swift-language-and -bekerja dengan-kontrol /


0

Di iOS 13 dan lebih tinggi saat Anda membuat proyek baru tanpa storyboard gunakan langkah-langkah di bawah ini:

  1. Buat proyek menggunakan Xcode 11 atau lebih tinggi

  2. Hapus ujung papan cerita dan kelas

  3. Tambahkan file baru dengan xib

  4. Perlu menyetel tampilan root sebagai UINavigationController SceneDelegate

  5. tambahkan kode di bawah func scene (_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {// Gunakan metode ini untuk mengkonfigurasi dan melampirkan UIWindow windowke UIWindowScene yang disediakan scene. // Jika menggunakan storyboard, windowproperti secara otomatis akan diinisialisasi dan dilampirkan ke adegan. // Delegasi ini tidak menyiratkan bahwa adegan atau sesi penghubung adalah baru (lihat application:configurationForConnectingSceneSessionsaja). // guard let _ = (scene sebagai? UIWindowScene) else {return}

    jika biarkan windowScene = scene sebagai? UIWindowScene {self.window = UIWindow (windowScene: windowScene) biarkan mainController = HomeViewController () sebagai HomeViewController biarkan navigationController = UINavigationController (rootViewController: mainController) self.window! .RootViewController = navigationController self.window! .MakeKeyAnd}

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.