Wie kann benutzerdefinierter UIViewController in Swift abgeleitet werden?

8

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.

%Vor%

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

zu erben

Wenn ich die Instanz von UsersViewControllerBase erstelle, funktioniert alles

%Vor%

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)

%Vor%

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:

%Vor%

Und ich würde init UsersViewController :

initiieren %Vor%

Aber leider funktioniert das nicht

    
Alex 19.11.2015, 16:23
quelle

3 Antworten

3

Wenn Sie einen View-Controller über instantiateViewControllerWithIdentifier instanziieren, läuft der Prozess im Wesentlichen wie folgt ab:

  • es findet eine Szene mit dieser Kennung;
  • bestimmt die Basisklasse für diese Szene; und
  • es gibt eine Instanz dieser Klasse zurück.

Und dann, wenn Sie zum ersten Mal auf view zugreifen, wird es:

  • Erstellen Sie die Ansichtshierarchie wie in dieser Storyboard-Szene beschrieben; und
  • Schließen Sie die Steckdosen an.

(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.

    
Rob 19.11.2015, 17:22
quelle
5

Sie haben also Ihre Basisklasse:

%Vor%

Und deine Unterklasse:

%Vor%

Um die Unterklasse richtig zu verwenden, müssen Sie Folgendes tun:

%Vor%     
yoninja 12.10.2016 06:50
quelle
0

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.

    
matt 19.11.2015 16:35
quelle