Ich möchte einen wiederverwendbaren View Controller UsersViewControllerBase
erstellen.
UsersViewControllerBase
erweitert UIViewController
und implementiert zwei Delegaten ( UITableViewDelegate
, UITableViewDataSource
) und hat zwei Ansichten ( UITableView
, UISegmentedControl
)
Ziel ist es, die Implementierung von UsersViewControllerBase
zu übernehmen und die segmentierten Elemente des segmentierten Steuerelements in UsersViewController
class anzupassen.
Der UsersViewControllerBase
ist im Storyboard vorhanden und alle Ausgänge sind verbunden, der Bezeichner wird angegeben.
Die Frage ist, wie kann ich den UsersViewController starten, um alle Ansichten und Funktionen von UsersViewControllerBase
Wenn ich die Instanz von UsersViewControllerBase
erstelle, funktioniert alles
Aber wenn ich die Instanz von UsersViewController
erstelle, bekomme ich nil
outlets
(Ich habe eine einfache UIViewController
erstellt und ihr im Storyboard die Klasse UsersViewController zugewiesen)
Es sieht so aus, als ob Ansichten nicht vererbt werden.
Ich würde erwarten, init Methode in UsersViewControllerBase
, die Controller mit Ansichten und Steckdosen vom Storyboard bekommt:
Und ich würde init UsersViewController
:
Aber leider funktioniert das nicht
Wenn Sie einen View-Controller über instantiateViewControllerWithIdentifier
instanziieren, läuft der Prozess im Wesentlichen wie folgt ab:
Und dann, wenn Sie zum ersten Mal auf view
zugreifen, wird es:
(Der Prozess ist eigentlich komplizierter, aber ich versuche, ihn auf die Schlüsselelemente in diesem Workflow zu reduzieren.)
Die Auswirkung dieses Workflows besteht darin, dass die Outlets und die Basisklasse durch die eindeutige Storyboard-ID bestimmt werden, die Sie an instantiateViewControllerWithIdentifier
übergeben. Für jede Unterklasse Ihrer Basisklasse benötigen Sie eine separate Storyboard-Szene und haben die Ausgänge für diese bestimmte Unterklasse angeschlossen.
Es gibt jedoch einen Ansatz, der das erreicht, was Sie angefordert haben. Anstatt die Storyboard-Szene für den View-Controller zu verwenden, können Sie stattdessen den View-Controller loadView
implementieren (nicht mit viewDidLoad
verwechseln) und die View-Hierarchie, die von der View-Controller-Klasse benötigt wird, programmatisch erstellen. Apple hatte eine schöne Einführung in diesen Prozess in ihrem View Controller Programmierhandbuch für iOS, , hat diese Diskussion inzwischen jedoch zurückgezogen, aber sie kann immer noch in ihrem Legacy-Dokumentation .
Nachdem ich das gesagt habe, wäre ich persönlich nicht gezwungen, zurück in die alte Welt der programmatisch erzeugten Ansichten zu gehen, es sei denn, es gibt einen sehr zwingenden Grund dafür. Ich könnte eher geneigt sein, den Ansatz der View-Controller-Unterklasse aufzugeben und etwas wie eine einzelne Klasse zu übernehmen (was bedeutet, dass ich wieder in der Welt der Storyboards bin) und dann einen Bezeichner übergeben, der das gewünschte Verhalten vorgibt diese Szene. Wenn Sie eine gewisse OO-Eleganz beibehalten möchten, können Sie benutzerdefinierte Klassen für die Datenquelle und den Delegaten basierend auf einer Eigenschaft erstellen, die Sie in dieser Ansichtssteuerelementklasse festlegen.
Ich wäre eher geneigt, diesen Weg einzuschlagen, wenn Sie ein wirklich dynamisches View-Controller-Verhalten benötigen, anstatt programmatisch erzeugte View-Hierarchien. Oder, noch einfacher, fahren Sie fort und übernehmen Sie Ihren ursprünglichen View-Controller-Unterklassenansatz und akzeptieren Sie einfach, dass Sie für jede Unterklasse separate Szenen im Storyboard benötigen.
Das Problem ist, dass Sie eine Szene im Storyboard erstellt haben, aber Sie haben der Ansicht des Ansichtscontrollers keine Subviews oder keine Verbindungspunkte hinzugefügt, daher ist die Oberfläche leer.
Wenn Sie eine Sammlung von Ansichten und Unteransichten in Verbindung mit Instanzen mehrerer verschiedener View-Controller-Klassen verwenden möchten, besteht die einfachste Möglichkeit darin, sie in ein .xib -Datei und lädt sie nach dem View-Loading-Prozess des View-Controllers in Code (zB in viewDidLoad
).
Wenn das Ziel lediglich darin besteht, die segmentierten Elemente der segmentierten Steuerung in verschiedenen Instanzen dieses Ansichtscontrollers anzupassen, besteht der einfachste Ansatz darin, eine Ansichtssteuerelementklasse und ein entsprechendes Schnittstellendesign zu haben und die Anpassung im Code durchzuführen. Sie können jedoch nur dieses segmentierte Steuerelement von seiner eigenen .xib laden, wenn es wichtig ist, dass Sie es visuell entwerfen.
Tags und Links view inheritance subclassing swift uiviewcontroller