XIB-Codegenerierung in Xamarin.iOS

Das Apple Interface Builder-Tool ("IB") kann verwendet werden, um Benutzeroberflächen visuell zu entwerfen. Die von IB erstellten Schnittstellendefinitionen werden in XIB-Dateien gespeichert. Widgets und andere Objekte in XIB-Dateien können eine "Klassenidentität" erhalten, die ein benutzerdefinierter Typ sein kann. Mithilfe benutzerdefinierter Typen können Sie das Verhalten von Widgets anpassen und benutzerdefinierte Widgets schreiben.

Diese Benutzerklassen sind normalerweise Unterklassen von Benutzeroberflächencontrollerklassen. Sie verfügen über Outlets (Eigenschaften) und Aktionen (Ereignisse), die mit Schnittstellenobjekten verbunden werden können. Zur Laufzeit wird die IB geladen. Zu diesem Zeitpunkt werden die Objekte erstellt, und die Outlets und Aktionen werden dynamisch mit den verschiedenen UI-Objekten verbunden. Beim Definieren dieser verwalteten Klassen müssen Sie alle Aktionen und Outlets so definieren, dass sie mit denen übereinstimmen, die IB erwartet. Visual Studio für Mac verwendet ein CodeBehind-ähnliches Modell, um den Code zu vereinfachen. Xcode verfügt über ein ähnliches Objective-C Modell. Aber das Xamarin.iOS-Codegenerierungsmodell und die Konventionen wurden optimiert, um .NET-Entwicklern besser vertraut zu sein.

XIB-Dateien und benutzerdefinierte Klassen

Es ist möglich, benutzerdefinierte Typen in XIB-Dateien zu definieren, zusätzlich zur Verwendung der vorhandenen Typen aus Cocoa Touch. Es ist auch möglich, Typen zu verwenden, die in anderen XIB-Dateien oder rein in C#-Code definiert sind. Derzeit sind dem Interface Builder die Details von Typen, die außerhalb der aktuellen XIB-Datei definiert sind, nicht bekannt, sodass sie nicht aufgelistet oder ihre benutzerdefinierten Outlets und Aktionen angezeigt werden. Die Aufhebung dieser Einschränkung ist für einige Zeit in der Zukunft geplant.

Benutzerdefinierte Klassen können in einer XIB-Datei mit dem Befehl "Unterklasse hinzufügen" auf der Registerkarte "Klassen" von Interface Builder definiert werden. Wir bezeichnen diese Klassen als "CodeBehind"-Klassen. Wenn die XIB-Datei die Entsprechungsdatei ".xib.designer.cs" im Projekt enthält, füllt Visual Studio für Mac sie automatisch mit Partiellen Klassendefinitionen für alle benutzerdefinierten Klassen in der XIB aus. Wir bezeichnen diese partiellen Klassen als "Designerklassen".

Generieren von Code

Die Codegenerierung wird durch das Vorhandensein einer {0}.xib.designer.cs-Datei für jede {0}XIB-Datei mit der Buildaktion Page aktiviert. Visual Studio für Mac generiert partielle Klassen in der Designerdatei für alle Benutzerklassen, die in der XIB-Datei gefunden werden können. Visual Studio für Mac generiert Eigenschaften für Outlets und partielle Methoden für Aktionen.

Die Designerdatei wird automatisch aktualisiert, wenn sich die XIB-Datei ändert und Visual Studio für Mac wieder den Fokus erhält. Das Vornehmen von Änderungen an der Designerdatei wird nicht empfohlen, da Änderungen beim nächsten Mal überschrieben werden, Visual Studio für Mac die Datei aktualisiert.

Registrierung und Namespaces

Visual Studio für Mac generiert die Designerklassen mithilfe des Standardnamespaces des Projekts für den Speicherort der Designerdatei. Dieses Verhalten ist mit der normalen Generierung von .NET-Projektnamespaces konsistent. Der Namespace der Designerdateien verwendet die Einstellungen "Standardnamespace" des Projekts und seine ".NET-Benennungsrichtlinien". Wenn sich der Standardnamespace Ihres Projekts ändert, verwenden die neu generierten Klassen den neuen Namespace. Nach der Regeneration stellen Sie möglicherweise fest, dass Ihre partiellen Klassen nicht mehr übereinstimmen.

Damit die Klasse von der Objective-C Runtime erkannt werden kann, wendet Visual Studio für Mac ein [Register (name)] Attribut auf die Klasse an. Obwohl Xamarin.iOS automatisch abgeleitete NSObjectKlassen registriert, verwendet es die vollqualifizierten .NET-Namen. Das von Visual Studio für Mac angewendete Attribut überschreibt das Xamarin.iOS-Verhalten, um sicherzustellen, dass jede Klasse mit dem namen registriert wird, der in der XIB-Datei verwendet wird. Fügen Sie das Attribut für alle benutzerdefinierten Klassen, die mithilfe von IB definiert sind, manuell hinzu, ohne Visual Studio für Mac zum Generieren von Designerdateien zu verwenden. Dadurch stimmen Ihre verwalteten Klassen mit den erwarteten Objective-C Klassennamen überein.

Klassen können nicht in mehr als einer XIB definiert werden, oder sie führen zu Konflikten.

Nicht Designer Klassenteile

Designer partielle Klassen sind nicht für die Verwendung wie bezweckt. Outlets sind privat, und es wird keine Basisklasse angegeben. Es wird erwartet, dass jede Klasse einen entsprechenden "Nicht-Designer"-Klassenteil in einer anderen Datei enthält. Die Nicht-Designer-Datei legt die Basisklasse fest, bearbeitet die Outlets und definiert Konstruktoren, die erforderlich sind, um die Klasse aus nativem Code zu instanziieren. Die XIB-Standardvorlagen enthalten die Klassenteile "non-designer", aber für alle anderen benutzerdefinierten Klassen, die Sie in einer XIB definieren, müssen Sie den Nicht-Designer-Teil manuell hinzufügen.

Diese Trennung mit partiellen Klassen ist aus Gründen der Flexibilität erforderlich. Beispielsweise könnten mehrere CodeBehind-Klassen eine gemeinsame verwaltete abstrakte Klasse unterklassen, die die klasse unterklassig von IB unterklassig werden soll.

Es ist üblich, CodeBehind-Klassen in einer {0}.xib.cs-Datei neben der {0}.xib.designer.cs-Designerdatei zu platzieren.

Generierte Aktionen und Outlets

In den partiellen Designerklassen generiert Visual Studio für Mac Eigenschaften, die allen in IB definierten verbundenen Outlets entsprechen, und partielle Methoden, die allen verbundenen Aktionen entsprechen.

Outlet-Eigenschaften

Designer Klassen enthalten Eigenschaften, die allen für die benutzerdefinierte Klasse definierten Outlets entsprechen. Diese Eigenschaften ermöglichen eine verzögerte Bindung. Sie sind ein Implementierungsdetail der Brücke zwischen Xamarin.iOS und Objective C. Stellen Sie sich diese als Äquivalent zu privaten Feldern vor, die nur aus der CodeBehind-Klasse verwendet werden sollen. Machen Sie das Feld öffentlich, indem Sie dem Feld im Nicht-Designer-Klassenteil den öffentlichen Accessor hinzufügen.

Wenn Die Ausgangseigenschaften so definiert sind, dass sie den Typ haben id (entspricht NSObject), bestimmt der Designercodegenerator derzeit den stärksten möglichen Typ basierend auf Objekten, die mit dieser Steckdose verbunden sind. Dieses Verhalten wird jedoch in zukünftigen Versionen möglicherweise nicht unterstützt. Es wird empfohlen, die Outlets beim Definieren der benutzerdefinierten Klasse explizit stark einzugeben.

Aktionseigenschaften

Designer Klassen enthalten partielle Methoden, die allen aktionen entsprechen, die für die benutzerdefinierte Klasse definiert sind. Diese Methoden verfügen nicht über eine Implementierung. Der Zweck der partiellen Methoden ist zweifach:

  1. Wenn Sie den Klassentext des Nicht-Designer-Klassenteils eingebenpartial, bietet Visual Studio für Mac an, die Signaturen aller nicht implementierten Teilmethoden automatisch zu vervollständigen.
  2. Die partiellen Methodensignaturen verfügen über ein Attribut, das sie für die Objective-C Welt verfügbar macht, sodass sie als entsprechende Aktion behandelt werden können.

Sie können die partielle Methode ignorieren und die Aktion implementieren, indem Sie das Attribut auf eine andere Methode anwenden. Oder lassen Sie ihn auf eine Basisklasse fallen.

Wenn Aktionen so definiert sind, dass sie den Absendertyp id haben (entspricht NSObject), bestimmt der Designercodegenerator derzeit den stärksten möglichen Typ basierend auf objekten, die mit dieser Aktion verbunden sind. Dieses Verhalten wird jedoch in zukünftigen Versionen möglicherweise nicht unterstützt. Es wird empfohlen, die Aktionen beim Definieren der benutzerdefinierten Klasse explizit stark einzugeben.

Diese partiellen Methoden werden nur für C# erstellt, da CodeDOM keine partiellen Methoden unterstützt. Sie werden nicht für andere Sprachen generiert.

XIB-Klassenverwendung

Manchmal möchten Benutzer aus mehreren XIB-Dateien auf dieselbe Klasse verweisen, z. B. mit Registerkartencontrollern. Sie können explizit auf die Klassendefinition aus einer anderen XIB-Datei verweisen oder denselben Klassennamen in der zweiten XIB-Datei erneut definieren.

Letzteres kann problematisch sein, da Visual Studio für Mac XIB-Dateien einzeln verarbeiten. Visual Studio für Mac können keine doppelten Definitionen erkennen und zusammenführen. Möglicherweise treten konflikte auf, wenn das Register-Attribut mehrmals angewendet wird, wenn dieselbe partielle Klasse in mehreren Designerdateien definiert ist. Aktuelle Versionen von Visual Studio für Mac versuchen, die Konflikte zu lösen, aber es funktioniert möglicherweise nicht immer wie erwartet. In Zukunft wird dieses Verhalten wahrscheinlich nicht mehr unterstützt, und stattdessen werden Visual Studio für Mac alle Typen, die in allen XIB-Dateien definiert sind, und verwalteten Code im Projekt direkt aus allen XIB-Dateien sichtbar machen.

Typauflösung

Typen, die in IB verwendet werden, sind Typnamen, die CLR-Typen mithilfe von Registerattributen zugeordnet sind Objective-C . Beim Generieren von Code löst Visual Studio für Mac CLR-Typen auf und qualifiziert die Typnamen vollständig für die Objective-C Typen. Diese Objective-C Typen werden vom Xamarin.iOS-Kern umschlossen.

Der Codegenerator kann derzeit keine CLR-Typen aus Objective-C Typnamen in Benutzercode oder Bibliotheken auflösen. In solchen Fällen wird der Typname wörtlich ausgegeben. Er muss den gleichen Namen wie der Objective-C Typ haben, um den CLR-Typ ordnungsgemäß aufzulösen. Der CLR-Typ muss sich im gleichen Namespace wie der Code befinden, der ihn verwendet. Zukünftige Versionen des Codegenerators werden alle Objective-C Typen im Projekt berücksichtigen.