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 erhalten möglicherweise eine "Klassenidentität", die ein benutzerdefinierter Typ sein kann. Mit benutzerdefinierten 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 Benutzeroberflächenobjekten verbunden. Beim Definieren dieser verwalteten Klassen müssen Sie alle Aktionen und Outlets so definieren, dass sie den von IB erwarteten entsprechen. Visual Studio für Mac verwendet ein CodeBehind-ähnliches Modell, um den Code zu vereinfachen. Xcode verfügt über ein ähnliches Objective-C Modell. Das Xamarin.iOS-Codegenerierungsmodell und die Konventionen wurden jedoch optimiert, um .NET-Entwicklern vertrauter 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 von Cocoa Touch. Es ist auch möglich, Typen zu verwenden, die in anderen XIB-Dateien oder ausschließlich in C#-Code definiert sind. Derzeit sind Interface Builder die Details der Typen, die außerhalb der aktuellen XIB-Datei definiert sind, nicht bekannt, sodass sie weder aufgeführt noch ihre benutzerdefinierten Outlets und Aktionen angezeigt werden. Das Entfernen dieser Einschränkung ist für einige Zeit in der Zukunft geplant.

Benutzerdefinierte Klassen können in einer XIB-Datei mithilfe des Befehls "Add Subclass" auf der Registerkarte "Classes" von Interface Builder definiert werden. Wir bezeichnen diese Klassen als "CodeBehind"-Klassen. Wenn die XIB-Datei eine ".xib.designer.cs"-Entsprechungsdatei im Projekt enthält, füllt Visual Studio für Mac sie automatisch mit partiellen Klassendefinitionen für alle benutzerdefinierten Klassen in der XIB-Datei auf. Wir bezeichnen diese partiellen Klassen als "Designerklassen".

Generieren von Code

Die Codegenerierung wird durch das Vorhandensein einer .xib.designer.cs-Datei für jede 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 Aktualisieren der Datei Visual Studio für Mac überschrieben werden.

Registrierung und Namespaces

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

Damit die Klasse von der Objective-C Laufzeit erkannt werden kann, wendet Visual Studio für Mac ein [Register (name)] -Attribut auf die -Klasse an. Obwohl Xamarin.iOS automatisch von abgeleitete NSObjectKlassen registriert, werden die vollqualifizierten .NET-Namen verwendet. Das von Visual Studio für Mac angewendete Attribut überschreibt das Xamarin.iOS-Verhalten, um sicherzustellen, dass jede Klasse mit dem in der XIB-Datei verwendeten Namen registriert ist. Fügen Sie das Attribut manuell für alle benutzerdefinierten Klassen hinzu, die mit IB definiert wurden, 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 mehreren XIB-Dateien definiert werden, oder sie verursachen einen Konflikt.

Nicht-Designer-Klassenteile

Partielle Designerklassen sind nicht so vorgesehen, dass sie wie besehen verwendet werden. 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 Datei "Nicht-Designer" legt die Basisklasse fest, bearbeitet die Outlets und definiert Konstruktoren, die zum Instanziieren der Klasse aus nativem Code erforderlich sind. Die XIB-Standardvorlagen verfügen über die Klassenteile "Nicht-Designer", aber für alle anderen benutzerdefinierten Klassen, die Sie in einer XIB-Datei 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önnen mehrere CodeBehind-Klassen eine gemeinsame verwaltete abstrakte Klasse untergliedern, die die Klasse untergliedert, die von IB unterklassigt werden soll.

Es ist üblich, CodeBehind-Klassen in einer XIB.cs-Datei neben der Designerdatei .xib.designer.cs zu speichern.

Generierte Aktionen und Outlets

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

Outleteigenschaften

Designerklassen enthalten Eigenschaften, die allen für die benutzerdefinierte Klasse definierten Outlets entsprechen. Diese Eigenschaften ermöglichen die verzögerte Bindung. Dabei handelt es sich um ein Implementierungsdetail der Bridge Xamarin.iOS zu Objective C. Stellen Sie sich diese als äquivalent zu privaten Feldern vor, die nur von 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 Outleteigenschaften als Typ id definiert sind (entspricht NSObject), bestimmt der Designercodegenerator zur Vereinfachung derzeit den stärksten Typ basierend auf Objekten, die mit diesem Outlet verbunden sind. Dieses Verhalten wird in zukünftigen Versionen jedoch möglicherweise nicht mehr unterstützt. Es wird empfohlen, die Outlets beim Definieren der benutzerdefinierten Klasse explizit stark einzugeben.

Aktionseigenschaften

Designerklassen 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 besteht aus zwei Teilen:

  1. Wenn Sie den Klassentext des Nicht-Designer-Klassenteils eingebenpartial, bieten Visual Studio für Mac an, die Signaturen aller nicht implementierten partiellen Methoden automatisch zu vervollständigen.
  2. Auf die partiellen Methodensignaturen wird ein Attribut angewendet, 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 es in eine Basisklasse fallen.

Wenn Aktionen als Absendertyp id definiert sind (entspricht NSObject), bestimmt der Designercodegenerator derzeit den stärksten Typ basierend auf Objekten, die mit dieser Aktion verbunden sind. Dieses Verhalten wird in zukünftigen Versionen jedoch möglicherweise nicht mehr 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-übergreifende Klassenverwendung

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

Der zweite Fall 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. Es kann zu Konflikten kommen, bei denen 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, funktionieren jedoch möglicherweise nicht immer wie erwartet. In Zukunft wird dieses Verhalten wahrscheinlich nicht mehr unterstützt, und stattdessen Visual Studio für Mac alle Typen, die in allen XIB-Dateien und verwaltetem Code im Projekt definiert sind, direkt aus allen XIB-Dateien sichtbar machen.

Typauflösung

In IB verwendete Typen sind Typnamen, die CLR-Typen mithilfe von Registerattributen zugeordnet werden 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 CLR-Typen derzeit nicht aus Objective-C Typnamen in Benutzercode oder Bibliotheken auflösen. In solchen Fällen wird der Typname ausführlich ausgegeben. Er muss den gleichen Namen wie der Objective-C Typ aufweisen, um den CLR-Typ ordnungsgemäß aufzulösen. Der CLR-Typ muss sich im selben Namespace wie der Code befinden, der ihn verwendet. In zukünftigen Versionen des Codegenerators werden alle Objective-C Typen im Projekt berücksichtigt.