Storyboard'lar kullanmadan nasıl yeni bir Swift projesi oluşturabilirim?


107

XCode 6'da yeni bir proje oluşturmak, Storyboard'ların devre dışı bırakılmasına izin vermez. Yalnızca Swift veya Objective-C'yi seçebilir ve Core Data'yı kullanabilir veya kullanamazsınız.

Film şeridini silmeyi ve projeden ana film şeridini kaldırmayı ve pencereyi didFinishLaunching'den manuel olarak ayarlamayı denedim

AppDelegate'te şuna sahibim:

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

Ancak, XCode bana bir hata veriyor:

'AppDelegate' sınıfının başlatıcısı yok

Bunu başaran var mı?


Yanıtlar:


71

windowVe testNavigationControllerdeğişkenlerini isteğe bağlı olarak işaretlemelisiniz :

var window : UIWindow?
var testNavigationController : UINavigationController?

Swift sınıfları, isteğe bağlı olmayan özelliklerin örnekleme sırasında başlatılmasını gerektirir:

Sınıflar ve yapılar, depolanan tüm özelliklerini, o sınıfın veya yapının bir örneği oluşturulduğunda uygun bir başlangıç ​​değerine ayarlamalıdır. Saklanan mülkler belirsiz durumda bırakılamaz.

İsteğe bağlı türdeki özellikler, özelliğin başlatma sırasında kasıtlı olarak "henüz bir değere sahip olmamasının" amaçlandığını gösteren bir sıfır değeriyle otomatik olarak başlatılır.

İsteğe bağlı değişkenleri kullanırken, bunları aşağıdakiler !gibi açmayı unutmayın :

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

1
Sonuna kadar cevabınızda her şey mükemmel bir anlam ifade ediyor. lütfen son bölümü açıklar mısın? açmak mı? bu gerekli mi
DanMoore

1
İsteğe bağlı olmayan bir özelliği sizin içinde saklayamazsınız AppDelegate(başlatma sırasında bir değere sahip olmadığı veya tembel olarak çözülmediği sürece). İsteğe bağlı bir özelliği saklarsanız ve olmadığından eminseniz , operatörü nilkullanarak "isteğe bağlılığından ayırırsınız" !.
akashivskyy

en iyi uygulama nedir, self.window! veya let window = ..?
laughingman

1
Pencerenizin var olduğundan eminseniz (ve bu özel durumda emin olabilirsiniz), ile gidebilirsiniz !.
akashivskyy

öyleyse bu, storyboard'ları kullandığımızda, backgroundColor'un bir şekilde varsayılan olarak ayarlandığı anlamına mı geliyor .white?
Honey

91

Storyboard'ları aşağıdakiler için kullanmamak için gereken her şey rootViewController:

1 · Şununla AppDelegate.swiftdeğiştir:

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 · Aşağıdakilerden bir ViewControlleralt sınıf oluşturun UIViewController:

import UIKit

class ViewController: UIViewController {

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

3 · Projeyi bir Xcode şablonundan oluşturduysanız:

  1. Anahtarın anahtar / değer çiftini "Main storyboard file base name"buradan kaldırın Info.plist.
  2. Film şeridi dosyasını silin Main.storyboard.

İlk kod parçacığında görebileceğiniz gibi if let, isteğe bağlı bir windowözelliğin sarmalını örtük olarak açmak yerine , isteğe bağlı özelliğin sarmalını açmak için sözdizimini tercih ederim . Burada if let a = a { }, isteğe abağlı olan if-statement içinde aynı ada sahip - isteğe bağlı olmayan bir referans haline gelecek şekilde kullanıyorum a.

Son olarak self., windowkendi sınıfı içindeki özelliğe referans verirken gerekli değildir .


1
Neden if let window = window {? Bunu anladım! window!Her seferinde kullanmanıza gerek kalmaması için .
Bilal Akil

@ 2unco Bunu çözdüğüne sevindim. Bu, hakkındaki cevabımın son bölümünde anlatılmıştır if let a = a {}.
tobiasdm

Aramayı ayarladıktan sonramakeKeyAndVisible() olacak şekilde taşırdım . Aksi takdirde, uygulamanın başlatılmasının sonunda pencerenin nasıl bir kök görünüm denetleyicisine sahip olmasının beklendiği konusunda bir uyarı alırsınız. rootViewController
Sebastien Martin

if let a = a { }tuhaf görünüyor. İsteğe bağlı olmayan referans için aynı değişken adını kullanmanın uygun olduğundan emin misiniz? Apple, Swift belgelerinde her zaman farklı isimler kullanır. Ayrıca, bu neden window!her seferinde kullanmaktan daha iyidir ?
ma11hew28

1. if let a = a { }gayet iyi. if let anA = a { }Kendinizi daha rahat hissettiriyorsa kullanabilirsiniz . 2. window!Açıkça isteğe bağlı bir sarmayı açtığınız için bir çalışma zamanı kontrolüdür. Swift'in bize sağladığı derleme süresi kontrollerini seviyorum, öyleyse neden kullanmayalım?
tobiasdm

13

ViewController'ınızı xib ile başlatmak istiyorsanız ve gezinti denetleyicisini kullanmanız gerekiyorsa. İşte bir kod parçası.

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

Aşağıdaki kodu deneyin:

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 kurulumuyla ilgisi olmayan cevabı buldum, film şeridini ve projeden referansın kaldırılması doğru şey. Hızlı sözdizimi ile ilgisi vardı.

Kod aşağıdaki gibidir:

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
    }

}

Peki çözüm başka bir cevapta ise neden kendi sorunuzu cevaplayasınız?
akashivskyy

sayfa güncellenmedi ve cevabı sadece gönderdikten sonra
görmedim

2

Bunu şu şekilde yapabilirsiniz:

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

Değişken pencere var mı: UIWindow? bunun isteğe bağlı bir özellik olduğunu belirtin.
Sean Dunford

Pekala, uygulama temsilcisine o olmadan ikinci bir var eklemeye çalıştım ve yukarıdaki ifademin doğru olduğunu buldum.
Sean Dunford

2

Controller ve xib kullanmanızı tavsiye ederim

MyViewController.swift ve MyViewController.xib

(File-> New-> File-> Cocoa Touch Class aracılığıyla oluşturabilir ve "ayrıca XIB dosyası oluştur" true, UIViewController alt sınıfını ayarlayabilirsiniz)

class MyViewController: UIViewController {
   .....    
}

ve AppDelegate.swift func applicationaşağıdaki kodu yazın

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

İş olmalı!


Bahsettiğiniz yolu denedim ama hata: Yakalanmamış istisna 'NSInternalInconsistencyException' nedeniyle uygulama sonlandırılıyor, neden: 'Pakette NIB yüklenemedi:
shripad20

2

Swift 3.0 için güncellendi:

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

2

Güncelleme: Swift 5 ve iOS 13:

  1. Tek Görünümlü Uygulama Oluşturun.
  2. Main.storyboard'u silin (sağ tıklayın ve silin).
  3. Film Şeridi AdınıInfo.plist dosyadaki varsayılan sahne yapılandırmasından silin :görüntü açıklamasını buraya girin
  4. Açın SceneDelegate.swiftve değiştirin 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 }
}

-e

 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

İşte bir UINavigationController için eksiksiz bir hızlı test örneği

        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

Neden boş bir uygulama oluşturmuyorsunuz? film şeridi benim için oluşturulmadı ...


0

Xcode 6'da (iOS 8) storyboard olmadan navigasyon tabanlı uygulama aşağıdaki gibi oluşturabiliriz:

  • Proje dilini Swift olarak seçerek boş bir uygulama oluşturun.

  • Xib arabirimiyle yeni kakao dokunmatik sınıfı dosyaları ekleyin. (ör. TestViewController)

  • Swift'de xib yani * .swift dosyasıyla etkileşime giren tek bir dosyamız var, .h ve .m dosyaları yok.

  • Xib'in kontrollerini iOS 7'deki gibi swift dosyası ile bağlayabiliriz.

Aşağıda, kontroller ve Swift ile çalışmak için bazı parçacıklar yer almaktadır.

//
//  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 dosyasındaki değişiklikler

//
//  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 adresinde kod örneği ve diğer bilgileri bulun -kontrollerle-çalışma /


0

İOS 13 ve üzeri sürümlerde, storyboard olmadan yeni proje oluşturduğunuzda aşağıdaki adımları kullanın:

  1. Xcode 11 veya üstünü kullanarak proje oluşturun

  2. Film şeridi ucunu ve sınıfını silin

  3. Xib ile yeni yeni dosya ekleyin

  4. Kök görünümünü UINavigationController SceneDelegate olarak ayarlamanız gerekiyor

  5. aşağıdaki kod işlev sahnesini ekleyin (_ sahne: UIScene, willConnectTo oturumu: UISceneSession, seçenekler connectionOptions: UIScene.ConnectionOptions) {// UIWindow'u isteğe bağlı olarak yapılandırmak ve windowsağlanan UIWindowScene'e eklemek için bu yöntemi kullanın scene. // Bir storyboard kullanılıyorsa, windowözellik otomatik olarak başlatılacak ve sahneye eklenecektir. // Bu delege, bağlantı sahnesinin veya oturumun yeni olduğu anlamına gelmez ( application:configurationForConnectingSceneSessionbunun yerine bakın ). // guard let _ = (? UIWindowScene olarak sahne) else {return}

    Eğer windowScene = sahne olsun? UIWindowScene {self.window = UIWindow (windowScene: windowScene), HomeViewController olarak mainController = HomeViewController () let navigationController = UINavigationController (rootViewController: mainController) self.window! .RootibleViewControl}.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.