webentwicklung-frage-antwort-db.com.de

Wie erstelle ich einen benutzerdefinierten Initialisierer für eine UIViewController-Unterklasse in Swift?

Entschuldigung, wenn dies schon einmal gefragt wurde, habe ich viel herumgesucht und viele Antworten stammen aus früheren Swift-Betas, wenn die Dinge anders waren. Ich kann anscheinend keine endgültige Antwort finden.

Ich möchte UIViewController subclass und habe einen benutzerdefinierten Initialisierer, der es mir ermöglicht, sie leicht in Code einzurichten. Ich habe Probleme damit in Swift.

Ich möchte eine init()-Funktion, mit der ich eine bestimmte NSURL übergeben kann, die ich dann mit dem View-Controller verwende. In meinen Augen sieht es so aus wie init(withImageURL: NSURL). Wenn ich diese Funktion hinzufüge, werden Sie aufgefordert, die Funktion init(coder: NSCoder) hinzuzufügen.

Ich glaube, das liegt daran, dass es in der Oberklasse mit dem Schlüsselwort required markiert ist. Also muss ich das in der Unterklasse machen? Ich füge es hinzu:

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

Was jetzt? Wird mein Spezialinitialisierer als convenience betrachtet? Ein ausgewiesener? Rufe ich einen Superinitialisierer an? Ein Initialisierer aus derselben Klasse?

Wie füge ich meinen speziellen Initialisierer einer UIViewController-Unterklasse hinzu?

63
Doug Smith
class ViewController: UIViewController {

    var imageURL: NSURL?

    // this is a convenient way to create this view controller without a imageURL
    convenience init() {
        self.init(imageURL: nil)
    }

    init(imageURL: NSURL?) {
        self.imageURL = imageURL
        super.init(nibName: nil, bundle: nil)
    }

    // if this view controller is loaded from a storyboard, imageURL will be nil

    /* Xcode 6
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    */

    // Xcode 7 & 8
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}
116
ylin0x81

Convenience-Initialisierer sind sekundär und unterstützen Initialisierer für ein Klasse. Sie können einen praktischen Initialisierer definieren, um ein bestimmtes .__ aufzurufen. Initialisierer aus derselben Klasse wie der Komfort-Initialisierer mit Einige der Parameter des angegebenen Initialisierers werden auf Standardwerte gesetzt. Sie können auch einen praktischen Initialisierer definieren, um eine Instanz von .__ zu erstellen. diese Klasse für einen bestimmten Anwendungsfall oder Eingabewerttyp.

Sie sind dokumentiert hier .

4
Vatsal Manot

Für diejenigen, die UI in Code schreiben

class Your_ViewController : UIViewController {

    let your_property : String

    init(your_property: String) {
        self.your_property = your_property
        super.init(nibName: nil, bundle: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) is not supported")
    }
}
3
Sasan Soroush

Wenn Sie beispielsweise ein benutzerdefiniertes Init für ein Popover benötigen, können Sie den folgenden Ansatz verwenden: 

Erstellen Sie eine benutzerdefinierte Init-Instanz, die die Super-Init-Instanz mit nibName und Bundle verwendet, und greifen Sie anschließend auf die View-Eigenschaft zu, um das Laden der View-Hierarchie zu erzwingen. 

Anschließend können Sie in der Funktion viewDidLoad die Ansichten mit den bei der Initialisierung übergebenen Parametern konfigurieren. 

import UIKit

struct Player {
    let name: String
    let age: Int
}

class VC: UIViewController {


@IBOutlet weak var playerName: UILabel!

let player: Player

init(player: Player) {
    self.player = player
    super.init(nibName: "VC", bundle: Bundle.main)
    if let view = view, view.isHidden {}
}

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

func configure() {
    playerName.text = player.name + "\(player.age)"
}
}

func showPlayerVC() {
    let foo = Player(name: "bar", age: 666)
    let vc = VC(player: foo)
    present(vc, animated: true, completion: nil)
}
0
rockdaswift