Swift: Özel ViewController başlatıcıları


87

UIViewControllerSwift'de alt sınıflara özel başlatıcıları nasıl eklersiniz ?

Bunun UIViewControllergibi görünen bir alt sınıf oluşturdum :

class MyViewController : UIViewController
{
    init(leftVC:UIViewController, rightVC:UIViewController, gap:Int)
    {
        self.leftVC = leftVC;
        self.rightVC = rightVC;
        self.gap = gap;

        super.init();

        setupScrollView();
        setupViewControllers();
    }
}

Çalıştırdığımda ölümcül bir hata alıyorum:

ölümcül hata: 'MyApp.MyViewController' sınıfı için uygulanmamış başlatıcı 'init (nibName: bundle :)' kullanımı

Başka bir yerde, özel bir başlatıcı eklerken birinin de geçersiz kılması gerektiğini okudum, init(coder aDecoder:NSCoder)bu yüzden bunu geçersiz kılalım initve ne olacağını görelim:

override init(coder aDecoder: NSCoder)
{
    super.init(coder: aDecoder);
}

Bunu eklersem, Xcode bundan şikayet eder self.leftVC is not initialized at super.init call. Yani sanırım bu da çözüm olamaz. Bu yüzden ViewController, Swift'deki bir alt sınıfa özel başlatıcıları nasıl düzgün bir şekilde ekleyebilirim merak ediyorum (çünkü Objective-C'de bu bir problem değil gibi görünüyor)?


Kendinizi nasıl somutlaştırmaya çalışıyorsunuz MyViewController?
Mike Pollard

Neden her şeyi viewDidLoad () 'da somutlaştırmıyorsunuz, orada onları istediğiniz gibi
başlatabilirsiniz

@MikePollard with dualViewCtrl = DualViewCtrl (leftVC: l, rightVC: r, gap: 50) ... initWithNib başlatıcısını kullanmam gerektiğini zaten öğrendim.
BadmintonCat

3
@tudoricc Çünkü genellikle, verilen parametrelerle başlatıcıda güvenli bir şekilde başlatılan örnek özellikleri istiyorsunuz. Bunu viewDidLoad'da yapamazsınız, o zamandan beri özelliklerin gerektiğinde kullanılabilir olacağı garanti edilemez.
BadmintonCat

Üzgünüm, aklımda viewDidLoad () 'u bir başlatıcı olarak görüyorum. açıklama için thanx
tudoricc

Yanıtlar:


125

Çözüldü! Kişi bu durumda nibName ile init olan atanmış başlatıcıyı çağırmak zorundadır, tabii ki ...

init(leftVC:UIViewController, rightVC:UIViewController, gap:Int)
{
    self.leftVC = leftVC
    self.rightVC = rightVC
    self.gap = gap

    super.init(nibName: nil, bundle: nil)

    setupScrollView()
    setupViewControllers()
}

31
Şu çirkin noktalı virgüllerden kurtulun :)
MobileMon

8
Noktalı virgülleri severim. Özellikle gülünç derecede ayrıntılı Cocoa / Cocoa-Touch API adları ve imzaları ile kodu daha az belirsiz hale getiriyorlar. Swift tasarımcılarından onları IMHO'yu kaldırmak için kötü bir karar.
BadmintonCat

25
Derlenmiş ikili bir karakteri yazmak ve onu etkilemiyorsa IMHO, sen onu yazmayın :) gerektiğini
Sam Soffes

33
@SamSoffes böylece (ekstra) boşluk kullanmıyorsunuz? Ve tüm sembolleri tek karakterler olarak mı karıştırıyorsun?
Victor Jalencas

8
Bu tartışma bana Silikon Vadisi'ndeki sekmeleri ve boşlukları hatırlatıyor
Aaron

14

Daha genel bir UIViewController için bunu Swift 2.0'dan itibaren kullanabilirsiniz.

init() {
    super.init(nibName: nil, bundle: nil)
}

11

Bunu tam olarak çözüp çözemediğinizden emin değilsiniz ... ancak sınıfınızın arayüzünün nasıl görünmesini istediğinize ve kodlayıcı işlevine gerçekten ihtiyacınız olup olmadığına bağlı olarak, aşağıdakileri de kullanabilirsiniz:

convenience required init(coder aDecoder: NSCoder)
{
    //set some defaults for leftVC, rightVC, and gap
    self.init(leftVC, rightVC, gap)
}

Yana init:leftVC:rightVC:gapbir başlatıcı belirlenmiş, sen uygulanması şartı yerine getirebilecek init:codero senin başlatıcısı belirlenmiş çağırır başlatıcısı bunu bir kolaylık yaparak.

Bu daha iyi olabilir

override init(coder aDecoder: NSCoder)
{
    super.init(coder: aDecoder);
}

çünkü bazı özellikleri başlatmanız gerekirse, onları yeniden yazmanız gerekir.


8

Swift 5

Eğer özel yazmak istiyorsanız için başlatıcı UIViewControllerile başlatılır hangistoryBoard.instantiateViewController(withIdentifier: "ViewControllerIdentifier")

Yalnızca Optionalözellikler için özel başlatıcı yazabilirsiniz .

class MyFooClass: UIViewController {
    var foo: Foo?

    init(with foo: Foo) {
        self.foo = foo
        super.init(nibName: nil, bundle: nil)
    }

    public required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.foo = nil
    }
}
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.