Як створити новий проект Swift, не використовуючи дошки розкадрів?


107

Створення нового проекту в XCode 6 не дозволяє вимкнути панелі розповідей. Ви можете вибрати лише Swift або Objective-C і використовувати основні дані чи ні.

Я спробував видалити дошку та з проекту, видаливши основну табло та вручну встановивши вікно з didFinishLaunching

У AppDelegate у мене є таке:

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" немає ініціалізаторів

Хтось досяг успіху в цьому?


Відповіді:


71

Ви повинні позначити windowі testNavigationControllerзмінні як необов'язкові:

var window : UIWindow?
var testNavigationController : UINavigationController?

Класи Swift вимагають ініціалізації необов'язкових властивостей під час створення інстанції:

Класи та структури повинні встановити всі їх збережені властивості на відповідне початкове значення до моменту створення екземпляра цього класу чи структури. Збережені властивості не можна залишити у невизначеному стані.

Властивості необов'язкового типу автоматично ініціалізуються зі значенням нуля, що вказує на те, що властивість навмисно призначена, щоб під час ініціалізації "ще не було значення".

Використовуючи необов’язкові змінні, не забудьте їх розгортати !, наприклад:

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

1
Усе має ідеальний сенс у вашій відповіді, до кінця. чи поясніть, будь ласка, цю останню частину розмотати? це потрібно?
DanMoore

1
Ви не можете зберігати необов'язкове властивість у своєму AppDelegate(якщо воно не має значення під час ініціалізації, або воно ліниво вирішено). Якщо ви зберігаєте необов'язковий ресурс і впевнені, що це не так nil, ви "знімаєте його з його необов'язкової" за допомогою !оператора.
акашівський

яка найкраща практика, self.window! або використовуючи, якщо нехай вікно = ..?
сміхун

1
Якщо ви впевнені, що ваше вікно існує (і ви можете бути впевнені в цьому конкретному випадку), ви можете піти з цим !.
акашівський

так це означає, що коли ми використовуємо розкадровки, фонColor це якось за замовчуванням .white?
Мед

91

Все, що потрібно, щоб не використовувати дошки розкадровок для rootViewController:

1 · Змінити AppDelegate.swiftна:

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 · Створіть ViewControllerпідклас з UIViewController:

import UIKit

class ViewController: UIViewController {

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

3 · Якщо ви створили проект із шаблону Xcode:

  1. Видалити пару ключ-значення для ключа "Main storyboard file base name"з Info.plist.
  2. Видаліть файл розповіді Main.storyboard.

Як ви бачите в першому фрагменті коду, замість того, щоб неявно розгортати необов'язковий, мені більше подобається if letсинтаксис для розгортання необов'язкової windowвластивості. Тут я використовую його if let a = a { }так, що необов'язковий aперетворюється на необов'язкове посилання всередині- ifStatement з тим самим назвою - a.

Нарешті, self.це не потрібно при посиланні на windowвластивість всередині його власного класу.


1
Чому if let window = window {? Я зрозумів це! Це так, що вам не потрібно використовувати window!щоразу.
Білал Акіль

@ 2unco Я радий, що ти це зрозумів. Це описано в останній частині моєї відповіді о if let a = a {}.
tobiasdm

Я б перемістив дзвінок, щоб makeKeyAndVisible()він був після налаштування rootViewController. Інакше ви отримаєте попередження про те, як очікується, що у вікні з'явиться контролер перегляду коренів у кінці запуску програми.
Себастьєн Мартін

if let a = a { }виглядає дивно. Ви впевнені, що добре використовувати те саме ім’я змінної для необов'язкової посилання? Apple завжди використовує різні назви у своїх документах Swift. Крім того, чому це краще, ніж просто використовувати window!щоразу?
ma11hew28

1. if let a = a { }ідеально добре. Ви можете використовувати, if let anA = a { }якщо це відчуває себе комфортніше. 2. window!це перевірка виконання, оскільки ви явно розгортаєте необов'язковий. Мені подобаються перевірки часу компіляції, які нам надає Swift, то чому б не використовувати його.
tobiasdm

13

Якщо ви хочете ініціалізувати свій viewController за допомогою xib і вам потрібно використовувати навігаційний контролер. Ось фрагмент коду.

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

Спробуйте наступний код:

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

Я знайшов відповідь, що це не мало нічого спільного з налаштуванням xcode, видаленням аркушів та посиланням на проект - це правильна річ. Це стосувалося швидкого синтаксису.

Код такий:

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
    }

}

Але навіщо відповідати на власне запитання, якщо рішення - в іншій відповіді?
акашівський

сторінка не оновлювалася, і я не побачила відповіді, лише після публікації
EhTd

2

Ви можете зробити це так:

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

Чи вар вікно: UIWindow? вказати, що це необов'язкова властивість?
Шон Данфорд

Ну я просто спробував додати другий вар в делегат додатка без нього і виявив, що моє вище твердження є правдивим.
Шон Данфорд

2

Рекомендую використовувати контролер та xib

MyViewController.swift і MyViewController.xib

(Ви можете створити через File-> New-> File-> Cocoa Touch Class і встановити "також створити XIB файл" true, підклас UIViewController)

class MyViewController: UIViewController {
   .....    
}

і In AppDelegate.swift func applicationнаписати наступний код

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

Це має бути робота!


Я спробував так само, як ви згадали, але помилка: Запуск програми через невдале виключення "NSInternalInconsistencyException", причина: "Не вдалося завантажити NIB в пакеті:
shripad20


2

Оновлення: Swift 5 та iOS 13:

  1. Створіть програму Single View.
  2. Видалити головну історію (клацніть правою кнопкою миші та видаліть).
  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()
    }
}

1

Ось повний приклад швидкого тестування для 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

Чому ви просто не створите порожню програму? дошка для мене не створена ...


0

У Xcode 6 (iOS 8) ми можемо створити додаток на базі навігації без розгортки, наприклад:

  • Створіть порожню програму, вибравши мову проекту як Swift.

  • Додайте нові файли сенсорного класу какао за допомогою інтерфейсу xib. (наприклад, TestViewController)

  • У швидкому випадку у нас взаємодіє лише один файл із файлом xib, тобто * .swift, файлів .h та .m немає.

  • Ми можемо з'єднати елементи керування xib із швидким файлом так само, як у iOS 7.

Далі наведено кілька фрагментів для роботи з елементами управління та 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()
    }

}

Зміни у файлі 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) {
    }

}

Знайдіть зразок коду та іншу інформацію на веб-сайті http://ashishkakkad.wordpress.com/2014/06/16/create-a-application-in-xcode-6-ios-8-without-storyborard-in-swift-language-and -робота-з-контролю /


0

У iOS 13 і новіших версіях, коли ви створюєте новий проект без розкадровки, використовуйте нижче кроки:

  1. Створіть проект за допомогою Xcode 11 або вище

  2. Видаліть ручку та клас клавіатури

  3. Додайте новий новий файл за допомогою xib

  4. Потрібно встановити кореневий вигляд як UINavigationController SceneDelegate

  5. додайте нижче код функції func (_ сцена: UIScene, willConnectTo сеанс: UISceneSession, параметри підключенняОпції: UIScene.ConnectionOptions) {// Використовуйте цей метод, щоб додатково налаштувати та приєднати вікно UIW windowдо наданого UIWindowScene scene. // Якщо використовується сценарій, windowвластивість автоматично ініціалізується та додається до сцени. // Цей делегат не означає, що з'єднувальна сцена або сеанс є новими (див. application:configurationForConnectingSceneSessionЗамість цього). // Охорона нехай _ = (сцена як? UIWindowScene) else {return}

    якщо нехай windowScene = сцена як? UIWindowScene {self.window = UIWindow (windowScene: windowScene) нехай mainController = HomeViewController () як HomeViewController дозволяє NaviController = UINavigationController (rootViewController: mainController) self.window!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.