Teilen über


Unified Storyboards in Xamarin.iOS

iOS 8 enthält einen neuen, einfacher zu verwendenden Mechanismus zum Erstellen der Benutzeroberfläche – dem einheitlichen Storyboard. Mit einem einzigen Storyboard, um alle verschiedenen Hardwarebildschirmgrößen abzudecken, können schnelle und reaktionsfähige Ansichten in einem "Design-once-, use-many"-Stil erstellt werden.

Da der Entwickler kein separates und spezifisches Storyboard für i Telefon- und iPad-Geräte mehr erstellen muss, haben sie die Flexibilität, Anwendungen mit einer gemeinsamen Schnittstelle zu entwerfen und diese Schnittstelle dann für verschiedene Größenklassen anzupassen. Auf diese Weise kann eine Anwendung an die Stärken jedes Formfaktors angepasst werden, und jede Benutzeroberfläche kann optimiert werden, um das beste Erlebnis zu bieten.

Größenklassen

Vor iOS 8 hat UIInterfaceOrientationUIInterfaceIdiom der Entwickler zwischen Hoch- und Querformat und i Telefon und iPad-Geräten unterschieden. In iOS8 wird die Ausrichtung und das Gerät mithilfe von Größenklassen bestimmt.

Geräte werden durch Größenklassen in vertikalen und horizontalen Achsen definiert, und es gibt zwei Arten von Größenklassen in iOS 8:

  • Normal – Dies gilt entweder für eine große Bildschirmgröße (z. B. ein iPad) oder ein Gadget, das den Eindruck einer großen Größe (z. B. einer UIScrollView
  • Kompakt – Dies gilt für kleinere Geräte (z. B. ein i Telefon). Diese Größe berücksichtigt die Ausrichtung des Geräts.

Wenn die beiden Konzepte zusammen verwendet werden, ist das Ergebnis ein 2 x 2-Raster, das die verschiedenen möglichen Größen definiert, die in beiden unterschiedlichen Ausrichtungen verwendet werden können, wie im folgenden Diagramm dargestellt:

Ein 2 x 2 Raster, das die verschiedenen möglichen Größen definiert, die in regulären und kompakten Ausrichtungen verwendet werden können

Der Entwickler kann einen Ansichtscontroller erstellen, der eine der vier Möglichkeiten verwendet, die zu verschiedenen Layouts führen würden (wie in den grafiken oben dargestellt).

iPad-Größenklassen

Das iPad verfügt aufgrund der Größe über eine normale Klassengröße für beide Ausrichtungen.

iPad-Größenklassen

i Telefon Größenklassen

Das i Telefon weist je nach Ausrichtung des Geräts unterschiedliche Größenklassen auf:

i Telefon Größenklassen

  • Wenn sich das Gerät im Hochformatmodus befindet, verfügt der Bildschirm über eine kompakte Klasse horizontal und normal vertikal
  • Wenn sich das Gerät im Querformatmodus befindet, werden die Bildschirmklassen vom Hochformatmodus umgekehrt.

i Telefon 6 plus Größenklassen

Die Größen entsprechen den früheren i Telefon s im Hochformat, aber unterschiedlich im Querformat:

i Telefon 6 plus Größenklassen

Da das i Telefon 6 Plus über einen großen Bildschirm verfügt, ist es in der Lage, im Querformatmodus eine Klasse für normale Breite zu haben.

Unterstützung für eine neue Bildschirmskala

Das i Telefon 6 Plus verwendet ein neues Retina HD-Display mit einem Bildschirmskalierungsfaktor von 3,0 (dreimal die ursprüngliche i Telefon Bildschirmauflösung). Um die bestmögliche Benutzererfahrung auf diesen Geräten zu bieten, fügen Sie neue Grafiken hinzu, die für diese Bildschirmskala entworfen wurden. In Xcode 6 und höher können Objektkataloge Bilder mit einer Größe von 1x, 2x und 3x enthalten. Fügen Sie einfach die neuen Bildressourcen hinzu, und iOS wählt die richtigen Ressourcen aus, wenn sie auf einem i Telefon 6 Plus ausgeführt werden.

Das Bildladeverhalten in iOS erkennt auch ein @3x Suffix für Bilddateien. Wenn der Entwickler beispielsweise eine Bildressource (in unterschiedlichen Auflösungen) in das Bündel der Anwendung mit den folgenden Dateinamen einschließt: MonkeyIcon.png, und MonkeyIcon@2x.pngMonkeyIcon@3x.png. Auf dem i Telefon 6 Plus wird das MonkeyIcon@3x.png Bild automatisch verwendet, wenn der Entwickler ein Bild mit dem folgenden Code lädt:

UIImage icon = UIImage.FromFile("MonkeyImage.png");

Dynamische Startbildschirme

Die Startbildschirmdatei wird als Begrüßungsbildschirm angezeigt, während eine iOS-Anwendung gestartet wird, um dem Benutzer Feedback zu geben, dass die App tatsächlich gestartet wird. Vor iOS 8 müsste der Entwickler mehrere Default.png Bildressourcen für jeden Gerätetyp, jede Ausrichtung und Bildschirmauflösung einschließen, auf der die Anwendung ausgeführt würde.

Neu bei iOS 8 kann der Entwickler eine einzelne Atomdatei .xib in Xcode erstellen, die Autolayout- und Größenklassen verwendet, um einen dynamischen Startbildschirm zu erstellen, der für jedes Gerät, jede Auflösung und Ausrichtung funktioniert. Dies reduziert nicht nur die Menge an Arbeit, die der Entwickler benötigt, um alle erforderlichen Imageressourcen zu erstellen und zu Standard, sondern reduziert die Größe des installierten Bündels der Anwendung.

Merkmale

Eigenschaften sind Eigenschaften, die verwendet werden können, um zu bestimmen, wie sich ein Layout ändert, während sich seine Umgebung ändert. Sie bestehen aus einer Reihe von Eigenschaften (dem HorizontalSizeClass und VerticalSizeClass basierend auf UIUserInterfaceSizeClass) sowie aus dem Schnittstellen-Idiom ( UIUserInterfaceIdiom) und der Anzeigeskala.

Alle oben genannten Zustände werden in einem Container umschlossen, auf den Apple als Trait Collection ( UITraitCollection) verweist, die nicht nur die Eigenschaften, sondern auch ihre Werte enthält.

Trait-Umgebung

Trait Environments sind eine neue Schnittstelle in iOS 8 und können eine Trait-Auflistung für die folgenden Objekte zurückgeben:

  • Bildschirme ( UIScreens ).
  • Windows ( UIWindows ).
  • Ansichtscontroller ( UIViewController ).
  • Views ( UIView ).
  • Präsentationscontroller ( UIPresentationController ).

Der Entwickler verwendet die trait Collection, die von einer Trait-Umgebung zurückgegeben wird, um zu bestimmen, wie eine Benutzeroberfläche gestaltet werden soll.

Alle Trait-Umgebungen machen eine Hierarchie wie im folgenden Diagramm dargestellt:

Das Hierarchiediagramm

Die Trait-Auflistung, die von jeder der oben genannten Trait-Umgebungen standardmäßig von der übergeordneten zu der untergeordneten Umgebung fließt.

Neben dem Abrufen der aktuellen Trait-Auflistung verfügt die Trait Environment über eine TraitCollectionDidChange Methode, die in den Unterklassen "View" oder "View Controller" überschrieben werden kann. Der Entwickler kann diese Methode verwenden, um alle UI-Elemente zu ändern, die von Eigenschaften abhängig sind, wenn sich diese Merkmale geändert haben.

Typische Trait-Sammlungen

In diesem Abschnitt werden die typischen Arten von Trait-Sammlungen behandelt, die der Benutzer beim Arbeiten mit iOS 8 erleben wird.

Im Folgenden finden Sie eine typische Trait-Sammlung, die der Entwickler auf einem i Telefon sehen kann:

Eigenschaft Wert
HorizontalSizeClass Kompakt
VerticalSizeClass Regulär
UserInterfaceIdom Telefonnummer
DisplayScale 2.0

Der obige Satz würde eine vollqualifizierte Trait-Auflistung darstellen, da sie Werte für alle eigenschaften hat.

Es ist auch möglich, eine Trait Collection zu haben, die einige seiner Werte fehlt (was Apple als nicht angegeben bezeichnet):

Eigenschaft Wert
HorizontalSizeClass Kompakt
VerticalSizeClass Nicht angegeben.
UserInterfaceIdom Nicht angegeben.
DisplayScale Nicht angegeben.

Im Allgemeinen gibt der Entwickler jedoch, wenn der Entwickler die Trait Environment für seine Trait-Sammlung fragt, eine vollqualifizierte Sammlung zurück, wie im obigen Beispiel zu sehen.

Wenn sich eine Trait-Umgebung (z. B. ein Ansichts- oder Ansichtscontroller) nicht innerhalb der aktuellen Ansichtshierarchie befindet, erhält der Entwickler möglicherweise nicht angegebene Werte für eine oder mehrere der Eigenschaftseigenschaften zurück.

Der Entwickler erhält auch eine teilweise qualifizierte Trait Collection, wenn sie eine der von Apple bereitgestellten Erstellungsmethoden verwenden, z UITraitCollection.FromHorizontalSizeClass. B. zum Erstellen einer neuen Sammlung.

Eine Operation, die für mehrere Trait-Sammlungen ausgeführt werden kann, besteht darin, sie miteinander zu vergleichen, was die Frage einer Trait-Auflistung umfasst, wenn sie eine andere enthält. Was mit Containment gemeint ist, ist, dass der Wert für alle in der zweiten Auflistung angegebenen Eigenschaften exakt mit dem Wert in der ersten Auflistung übereinstimmen muss.

Um zwei Merkmale zu testen, verwenden Sie die Methode der Übergabe des Werts des zu testenden Merkmals.To test two traits use the Contains method of the UITraitCollection passing in the value of the trait to be test.

Der Entwickler kann die Vergleiche manuell im Code ausführen, um zu bestimmen, wie Ansichten oder Ansichtscontroller layoutt werden. Verwendet diese Methode jedoch intern, UIKit um einige ihrer Funktionen bereitzustellen, wie z. B. im Darstellungsproxy.

Darstellungsproxy

Der Darstellungsproxy wurde in früheren Versionen von iOS eingeführt, damit Entwickler die Eigenschaften ihrer Ansichten anpassen können. Es wurde in iOS 8 erweitert, um Trait Collections zu unterstützen.

Darstellungsproxys enthalten jetzt eine neue Methode, AppearanceForTraitCollectiondie einen neuen Darstellungsproxy für die angegebene Trait-Auflistung zurückgibt, die übergeben wurde. Alle Anpassungen, die der Entwickler für diesen Darstellungsproxy ausführt, wirkt sich nur auf Ansichten aus, die der angegebenen Trait-Auflistung entsprechen.

Im Allgemeinen wird der Entwickler eine teilweise angegebene Trait-Auflistung an die AppearanceForTraitCollection Methode übergeben, z. B. eine, die gerade eine horizontale Größenklasse von Compact angegeben hat, sodass sie jede Ansicht in der Anwendung anpassen können, die horizontal kompakt ist.

UIImage

Eine weitere Klasse, der Apple Trait Collection hinzugefügt hat, ist UIImage. In der Vergangenheit musste der Entwickler eine @1X und @2x Version aller Bitmap-Grafikressource angeben, die sie in die Anwendung aufnehmen würden (z. B. ein Symbol).

iOS 8 wurde erweitert, um es dem Entwickler zu ermöglichen, mehrere Versionen eines Bilds in einen Bildkatalog basierend auf einer Trait-Sammlung aufzunehmen. Beispielsweise könnte der Entwickler ein kleineres Bild für die Arbeit mit einer Compact Trait-Klasse und ein Bild in voller Größe für jede andere Sammlung enthalten.

Wenn eines der Bilder innerhalb einer UIImageView Klasse verwendet wird, zeigt die Bildansicht automatisch die richtige Version des Bilds für die Trait-Auflistung an. Wenn sich die Trait-Umgebung ändert (z. B. der Benutzer wechselt das Gerät vom Hochformat ins Querformat), wählt die Bildansicht automatisch die neue Bildgröße aus, um der neuen Trait-Auflistung zu entsprechen, und ändert die Größe entsprechend der aktuellen Version des angezeigten Bilds.

UIImageAsset

Apple hat iOS 8 UIImageAsset eine neue Klasse hinzugefügt, um dem Entwickler noch mehr Kontrolle über die Bildauswahl zu geben.

Ein Bildobjekt fasst alle verschiedenen Versionen eines Bilds um und ermöglicht es dem Entwickler, ein bestimmtes Bild zu fragen, das einer Trait-Auflistung entspricht, die übergeben wurde. Bilder können direkt aus einer Bildressource hinzugefügt oder daraus entfernt werden.

Weitere Informationen zu Bildressourcen finden Sie in der Dokumentation zu "UIImageAsset" von Apple.

Kombinieren von Trait-Sammlungen

Eine weitere Funktion, die ein Entwickler für Trait-Sammlungen ausführen kann, besteht darin, zwei zusammen hinzuzufügen, die zu der kombinierten Auflistung führen, wobei die nicht angegebenen Werte aus einer Auflistung durch die angegebenen Werte in einer zweiten ersetzt werden. Dies erfolgt mithilfe der FromTraitsFromCollections Methode der UITraitCollection Klasse.

Wie oben erwähnt, wird der Wert auf die angegebene Version festgelegt, wenn eines der Merkmale in einer der Trait Collections nicht angegeben ist und in einer anderen angegeben wird. Wenn jedoch mehrere Versionen eines bestimmten Werts angegeben sind, ist der Wert aus der letzten Trait-Auflistung der verwendete Wert.

Controller für adaptive Ansicht

In diesem Abschnitt werden die Details erläutert, wie die iOS-Ansichts- und Ansichtscontroller die Konzepte von Traits und Size Classes übernommen haben, um in den Anwendungen des Entwicklers automatisch adaptiver zu sein.

Controller für geteilte Ansicht

Eine der View Controller-Klassen, die die meisten in iOS 8 geändert hat, ist die UISplitViewController Klasse. In der Vergangenheit würde der Entwickler häufig einen Split View Controller auf der iPad-Version der Anwendung verwenden und dann eine völlig andere Version ihrer Ansichtshierarchie für die i Telefon-Version der App bereitstellen.

In iOS 8 ist die UISplitViewController Klasse auf beiden Plattformen (iPad und i Telefon) verfügbar, mit der der Entwickler eine View Controller-Hierarchie erstellen kann, die sowohl für i Telefon als auch für iPad funktioniert.

Wenn sich ein i Telefon im Querformat befindet, zeigt der Split View Controller seine Ansichten nebeneinander an, genau wie bei der Anzeige auf einem iPad.

Überschreibende Merkmale

Trait Environments kaskadieren vom übergeordneten Container bis zu den untergeordneten Containern, wie in der folgenden Grafik, die einen Split View Controller auf einem iPad in der Querformatausrichtung zeigt:

Ein Geteilter Ansichtscontroller auf einem iPad im Querformat

Da das iPad sowohl in horizontaler als auch vertikaler Ausrichtung über eine normale Größenklasse verfügt, zeigt die geteilte Ansicht sowohl die Master- als auch die Detailansicht an.

Auf einem i Telefon, bei dem die Größenklasse in beiden Ausrichtungen kompakt ist, zeigt der Split View Controller nur die Detailansicht an, wie unten dargestellt:

Der Controller für geteilte Ansicht zeigt nur die Detailansicht an.

In einer Anwendung, in der der Entwickler sowohl die Master- als auch die Detailansicht auf einem i Telefon im Querformat anzeigen möchte, muss der Entwickler einen übergeordneten Container für den Split View Controller einfügen und die Trait-Auflistung außer Kraft setzen. Wie in der folgenden Grafik dargestellt:

Der Entwickler muss einen übergeordneten Container für den Split View Controller einfügen und die Trait-Auflistung außer Kraft setzen.

A UIView wird als übergeordnetes Element des Geteilten Ansichtscontrollers festgelegt, und die SetOverrideTraitCollection Methode wird für die Ansicht aufgerufen, die eine neue Trait-Auflistung übergibt und auf den Controller für geteilte Ansicht ausgerichtet ist. Die neue Trait-Auflistung setzt die HorizontalSizeClassEinstellung Regularauf , sodass der Split View Controller sowohl die Master- als auch die Detailansicht auf einem i Telefon in der Querformatausrichtung anzeigt.

Beachten Sie, dass die VerticalSizeClass Einstellung auf unspecified", wodurch die neue Trait-Auflistung der Trait-Auflistung auf dem übergeordneten Element hinzugefügt werden kann, was zu einem Compact VerticalSizeClass für den untergeordneten Geteilten Ansichtscontroller führt.

Trait-Änderungen

In diesem Abschnitt wird ausführlich erläutert, wie sich die Trait Collections ändern, wenn sich die Trait-Umgebung ändert. Wenn das Gerät beispielsweise von Hochformat in Querformat gedreht wird.

Übersicht über das Hochformat zum Querformat

Zunächst führt iOS 8 einige Setups durch, um sich auf den Übergang vorzubereiten. Als Nächstes animiert das System den Übergangszustand. Schließlich sauber iOS 8 alle temporären Zustände, die während des Übergangs erforderlich sind.

iOS 8 bietet mehrere Rückrufe, die der Entwickler verwenden kann, um an der Trait-Änderung teilzunehmen, wie in der folgenden Tabelle dargestellt:

Phase Rückruf Beschreibung
Setup
  • WillTransitionToTraitCollection
  • TraitCollectionDidChange
  • Diese Methode wird am Anfang einer Trait-Änderung aufgerufen, bevor eine Trait-Auflistung auf den neuen Wert festgelegt wird.
  • Die Methode wird aufgerufen, wenn sich der Wert der Trait-Auflistung geändert hat, aber bevor eine Animation stattfindet.
Animation WillTransitionToTraitCollection Der Übergangskoordinator, der an diese Methode übergeben wird, verfügt über eine AnimateAlongside Eigenschaft, mit der der Entwickler Animationen hinzufügen kann, die zusammen mit den Standardanimationen ausgeführt werden.
Bereinigung WillTransitionToTraitCollection Stellt eine Methode bereit, mit der Entwickler ihren eigenen sauber up-Code einschließen können, nachdem der Übergang erfolgt ist.

Die WillTransitionToTraitCollection Methode eignet sich hervorragend zum Animieren von Ansichtscontrollern zusammen mit den Änderungen der Trait-Auflistung. Die WillTransitionToTraitCollection Methode ist nur für Ansichtscontroller ( UIViewController) und nicht für andere Trait-Umgebungen verfügbar, z UIViews. B. .

Dies TraitCollectionDidChange eignet sich hervorragend für die Arbeit mit der UIView Klasse, in der der Entwickler die Benutzeroberfläche aktualisieren möchte, während sich die Eigenschaften ändern.

Reduzieren der Controller für geteilte Ansicht

Sehen wir uns nun genauer an, was passiert, wenn ein Geteilter Ansichtscontroller von einer zweiSpalte in eine Spaltenansicht reduziert wird. Im Rahmen dieser Änderung gibt es zwei Prozesse, die auftreten müssen:

  • Standardmäßig verwendet der Controller für geteilte Ansicht den primären Ansichtscontroller als Ansicht nach dem Reduzieren. Der Entwickler kann dieses Verhalten außer Kraft setzen, indem die GetPrimaryViewControllerForCollapsingSplitViewController Methode der UISplitViewControllerDelegate Ansichtscontroller überschrieben wird, die im reduzierten Zustand angezeigt werden sollen.
  • Der sekundäre Ansichtscontroller muss mit dem primären Ansichtscontroller zusammengeführt werden. Im Allgemeinen muss der Entwickler keine Maßnahmen für diesen Schritt ergreifen. der Split View Controller umfasst die automatische Verarbeitung dieser Phase basierend auf dem Hardwaregerät. Es kann jedoch einige Spezielle Fälle geben, in denen der Entwickler mit dieser Änderung interagieren möchte. Durch Aufrufen der CollapseSecondViewController Methode kann UISplitViewControllerDelegate der Masteransichtscontroller angezeigt werden, wenn der Collapse auftritt, anstelle der Detailansicht.

Erweitern des Geteilten Ansichtscontrollers

Sehen wir uns nun genauer an, was passiert, wenn ein Split View Controller aus einem reduzierten Zustand erweitert wird. Erneut gibt es zwei Phasen, die auftreten müssen:

  • Definieren Sie zuerst den neuen primären Ansichtscontroller. Standardmäßig verwendet der Controller für geteilte Ansicht automatisch den primären Ansichtscontroller aus der reduzierten Ansicht. Auch hier kann der Entwickler dieses Verhalten mithilfe der GetPrimaryViewControllerForExpandingSplitViewController Methode der UISplitViewControllerDelegate .
  • Nachdem der primäre Ansichtscontroller ausgewählt wurde, muss der sekundäre Ansichtscontroller neu erstellt werden. Auch hier umfasst der Split View Controller die automatische Verarbeitung dieser Phase basierend auf dem Hardwaregerät. Der Entwickler kann dieses Verhalten überschreiben, indem die SeparateSecondaryViewController Methode der UISplitViewControllerDelegate .

In einem Geteilten Ansichtscontroller spielt der primäre Ansichtscontroller sowohl bei der Erweiterung als auch beim Reduzieren der Ansichten eine Rolle, indem die CollapseSecondViewController Methoden und SeparateSecondaryViewController Methoden der UISplitViewControllerDelegateAnsicht implementiert werden. UINavigationController implementiert diese Methoden, um den sekundären Ansichtscontroller automatisch zu pushen und aufzurufen.

Anzeigen von Ansichtscontrollern

Eine weitere Änderung, die Apple an iOS 8 vorgenommen hat, ist die Art und Weise, wie der Entwickler Ansichtscontroller anzeigt. Wenn die Anwendung in der Vergangenheit einen Blattansichtscontroller (z. B. einen Tabellenansichtscontroller) hatte und der Entwickler eine andere angezeigt hat (z. B. als Reaktion auf den Benutzer, der auf eine Zelle tippt), gelangt die Anwendung zurück über die Controllerhierarchie zum Navigationsansichtscontroller und ruft die PushViewController Methode dafür auf, um die neue Ansicht anzuzeigen.

Dies stellte eine sehr enge Kopplung zwischen dem Navigationscontroller und der Umgebung dar, in der sie ausgeführt wurde. In iOS 8 hat Apple dies entkoppelt, indem zwei neue Methoden bereitgestellt werden:

  • ShowViewController – Passt sich an die Anzeige des neuen Ansichtscontrollers basierend auf seiner Umgebung an. In einer UINavigationController Folie wird beispielsweise einfach die neue Ansicht auf den Stapel verschoben. In einem Geteilten Ansichtscontroller wird der neue Ansichtscontroller auf der linken Seite als neuer primärer Ansichtscontroller angezeigt. Wenn kein Containeransichtscontroller vorhanden ist, wird die neue Ansicht als modaler Ansichtscontroller angezeigt.
  • ShowDetailViewController – Funktioniert ähnlich wie ShowViewControllerbei einem Split View Controller, wird jedoch auf einem Split View Controller implementiert, um die Detailansicht durch den neuen Ansichtscontroller zu ersetzen, der übergeben wird. Wenn der Controller für geteilte Ansicht reduziert ist (wie in einer i Telefon Anwendung dargestellt), wird der Aufruf an die ShowViewController Methode umgeleitet, und die neue Ansicht wird als primärer Ansichtscontroller angezeigt. Wenn kein Containeransichtscontroller vorhanden ist, wird die neue Ansicht als modaler Ansichtscontroller angezeigt.

Diese Methoden funktionieren, indem sie mit dem Leaf View Controller beginnen und die Ansichtshierarchie durchlaufen, bis sie den richtigen Containeransichtscontroller finden, um die Anzeige der neuen Ansicht zu verarbeiten.

Entwickler können eigene benutzerdefinierte Ansichtscontroller implementieren und ShowDetailViewController verwendenShowViewController, um die gleiche automatisierte Funktionalität zu erhalten, die UINavigationController sie UISplitViewController bereitstellt.

Funktionsweise

In diesem Abschnitt werden wir uns ansehen, wie diese Methoden tatsächlich in iOS 8 implementiert werden. Sehen wir uns zunächst die neue GetTargetForAction Methode an:

Die neue GetTargetForAction-Methode

Diese Methode führt die Hierarchiekette durch, bis der richtige Containeransichtscontroller gefunden wird. Zum Beispiel:

  1. Wenn eine ShowViewController Methode aufgerufen wird, ist der erste Ansichtscontroller in der Kette, der diese Methode implementiert, der Navigationscontroller, sodass sie als übergeordnetes Element der neuen Ansicht verwendet wird.
  2. Wenn stattdessen eine ShowDetailViewController Methode aufgerufen wurde, ist der Geteilte Ansichtscontroller der erste Ansichtscontroller, der sie implementiert, sodass sie als übergeordnetes Element verwendet wird.

Die GetTargetForAction Methode funktioniert, indem sie einen Ansichtscontroller suchen, der eine bestimmte Aktion implementiert, und dann den Ansichtscontroller fragt, ob diese Aktion empfangen werden soll. Da diese Methode öffentlich ist, können Entwickler eigene benutzerdefinierte Methoden erstellen, die genau wie die integrierten ShowViewController Und ShowDetailViewController Methoden funktionieren.

Adaptive Präsentation

In iOS 8 hat Apple Popover-Präsentationen ( UIPopoverPresentationController) auch adaptive gemacht. Ein Popover-Präsentationsansichtscontroller zeigt also automatisch eine normale Popover-Ansicht in einer normalen Größenklasse an, zeigt sie aber in einer horizontal kompakten Größenklasse (z. B. auf einem i Telefon) vollbildig an.

Um die Änderungen im einheitlichen Storyboardsystem zu berücksichtigen, wurde ein neues Controllerobjekt erstellt, um die präsentierten Ansichtscontroller zu verwalten . UIPresentationController Dieser Controller wird ab dem Zeitpunkt erstellt, an dem der Ansichtscontroller angezeigt wird, bis er geschlossen wird. Da es sich um eine verwaltete Klasse handelt, kann sie als Superklasse über dem Ansichtscontroller betrachtet werden, da sie auf Geräteänderungen reagiert, die sich auf den Ansichtscontroller (z. B. die Ausrichtung) auswirken, die dann wieder in den Ansichtscontroller der Präsentationscontroller-Steuerelemente eingespeist werden.

Wenn der Entwickler einen View Controller mit der PresentViewController Methode präsentiert, wird die Verwaltung des Präsentationsprozesses übergeben UIKit. UIKit behandelt (unter anderem) den richtigen Controller für die zu erstellende Formatvorlage, wobei die einzige Ausnahme ist, wenn ein Ansichtscontroller die Formatvorlage festgelegt UIModalPresentationCustomhat. Hier kann die Anwendung einen eigenen PresentationController bereitstellen, anstatt den UIKit Controller zu verwenden.

Benutzerdefinierte Präsentationsformatvorlagen

Mit einem benutzerdefinierten Präsentationsstil haben Entwickler die Möglichkeit, einen benutzerdefinierten Präsentationscontroller zu verwenden. Dieser benutzerdefinierte Controller kann verwendet werden, um die Darstellung und das Verhalten der Ansicht zu ändern, der sie zugeordnet ist.

Arbeiten mit Größenklassen

Das adaptive Fotos Xamarin-Projekt, das in diesem Artikel enthalten ist, enthält ein funktionierendes Beispiel für die Verwendung von Größenklassen und adaptiven Ansichtscontrollern in einer iOS 8 Unified Interface-Anwendung.

Während die Anwendung die Benutzeroberfläche vollständig aus Code erstellt, im Gegensatz zum Erstellen eines Unified Storyboards mit dem Schnittstellen-Generator von Xcode, gelten dieselben Techniken.

Sehen wir uns nun genauer an, wie das Projekt "Adaptive Fotos" mehrere der Größenklassenfeatures in iOS 8 implementiert, um eine adaptive Anwendung zu erstellen.

Anpassung an Änderungen der Trait-Umgebung

Wenn sie die Anwendung adaptive Fotos auf einem i Telefon ausführen, zeigt der Benutzer das Gerät vom Hochformat in das Querformat an, und der Controller für geteilte Ansicht zeigt sowohl die Master- als auch die Detailansicht an:

Der Controller für geteilte Ansicht zeigt sowohl die Master- als auch die Detailansicht an, wie hier dargestellt.

Dazu wird die UpdateConstraintsForTraitCollection Methode des Ansichtscontrollers überschrieben und die Einschränkungen basierend auf dem Wert der VerticalSizeClass. Zum Beispiel:

public void UpdateConstraintsForTraitCollection (UITraitCollection collection)
{
    var views = NSDictionary.FromObjectsAndKeys (
        new object[] { TopLayoutGuide, ImageView, NameLabel, ConversationsLabel, PhotosLabel },
        new object[] { "topLayoutGuide", "imageView", "nameLabel", "conversationsLabel", "photosLabel" }
    );

    var newConstraints = new List<NSLayoutConstraint> ();
    if (collection.VerticalSizeClass == UIUserInterfaceSizeClass.Compact) {
        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("|[imageView]-[nameLabel]-|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("[imageView]-[conversationsLabel]-|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("[imageView]-[photosLabel]-|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("V:|[topLayoutGuide]-[nameLabel]-[conversationsLabel]-[photosLabel]",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("V:|[topLayoutGuide][imageView]|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.Add (NSLayoutConstraint.Create (ImageView, NSLayoutAttribute.Width, NSLayoutRelation.Equal,
            View, NSLayoutAttribute.Width, 0.5f, 0.0f));
    } else {
        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("|[imageView]|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("|-[nameLabel]-|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("|-[conversationsLabel]-|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("|-[photosLabel]-|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));

        newConstraints.AddRange (NSLayoutConstraint.FromVisualFormat ("V:[topLayoutGuide]-[nameLabel]-[conversationsLabel]-[photosLabel]-20-[imageView]|",
            NSLayoutFormatOptions.DirectionLeadingToTrailing, null, views));
    }

    if (constraints != null)
        View.RemoveConstraints (constraints.ToArray ());

    constraints = newConstraints;
    View.AddConstraints (constraints.ToArray ());
}

Hinzufügen von Übergangsanimationen

Wenn der Split View Controller in der adaptiven Fotos Anwendung von reduziert in erweitert wechselt, werden Animationen den Standardanimationen hinzugefügt, indem die WillTransitionToTraitCollection Methode des Ansichtscontrollers überschrieben wird. Zum Beispiel:

public override void WillTransitionToTraitCollection (UITraitCollection traitCollection, IUIViewControllerTransitionCoordinator coordinator)
{
    base.WillTransitionToTraitCollection (traitCollection, coordinator);
    coordinator.AnimateAlongsideTransition ((UIViewControllerTransitionCoordinatorContext) => {
        UpdateConstraintsForTraitCollection (traitCollection);
        View.SetNeedsLayout ();
    }, (UIViewControllerTransitionCoordinatorContext) => {
    });
}

Überschreiben der Trait-Umgebung

Wie oben gezeigt, erzwingt die Anwendung adaptive Fotos den Split View Controller, sowohl die Details als auch die Masteransichten anzuzeigen, wenn sich das i Telefon-Gerät in der Querformatansicht befindet.

Dazu wurde der folgende Code im Ansichtscontroller verwendet:

private UITraitCollection forcedTraitCollection = new UITraitCollection ();
...

public UITraitCollection ForcedTraitCollection {
    get {
        return forcedTraitCollection;
    }

    set {
        if (value != forcedTraitCollection) {
            forcedTraitCollection = value;
            UpdateForcedTraitCollection ();
        }
    }
}
...

public override void ViewWillTransitionToSize (SizeF toSize, IUIViewControllerTransitionCoordinator coordinator)
{
    ForcedTraitCollection = toSize.Width > 320.0f ?
         UITraitCollection.FromHorizontalSizeClass (UIUserInterfaceSizeClass.Regular) :
         new UITraitCollection ();

    base.ViewWillTransitionToSize (toSize, coordinator);
}

public void UpdateForcedTraitCollection ()
{
    SetOverrideTraitCollection (forcedTraitCollection, viewController);
}

Erweitern und Reduzieren des Geteilten Ansichtscontrollers

Als Nächstes untersuchen wir, wie das erweiternde und reduzierende Verhalten des Geteilten Ansichtscontrollers in Xamarin implementiert wurde. AppDelegateWenn der Controller für geteilte Ansicht erstellt wird, wird der Stellvertretung zugewiesen, um diese Änderungen zu behandeln:

public class SplitViewControllerDelegate : UISplitViewControllerDelegate
{
    public override bool CollapseSecondViewController (UISplitViewController splitViewController,
        UIViewController secondaryViewController, UIViewController primaryViewController)
    {
        AAPLPhoto photo = ((CustomViewController)secondaryViewController).Aapl_containedPhoto (null);
        if (photo == null) {
            return true;
        }

        if (primaryViewController.GetType () == typeof(CustomNavigationController)) {
            var viewControllers = new List<UIViewController> ();
            foreach (var controller in ((UINavigationController)primaryViewController).ViewControllers) {
                var type = controller.GetType ();
                MethodInfo method = type.GetMethod ("Aapl_containsPhoto");

                if ((bool)method.Invoke (controller, new object[] { null })) {
                    viewControllers.Add (controller);
                }
            }

            ((UINavigationController)primaryViewController).ViewControllers = viewControllers.ToArray<UIViewController> ();
        }

        return false;
    }

    public override UIViewController SeparateSecondaryViewController (UISplitViewController splitViewController,
        UIViewController primaryViewController)
    {
        if (primaryViewController.GetType () == typeof(CustomNavigationController)) {
            foreach (var controller in ((CustomNavigationController)primaryViewController).ViewControllers) {
                var type = controller.GetType ();
                MethodInfo method = type.GetMethod ("Aapl_containedPhoto");

                if (method.Invoke (controller, new object[] { null }) != null) {
                    return null;
                }
            }
        }

        return new AAPLEmptyViewController ();
    }
}

Die SeparateSecondaryViewController Methode testet, ob ein Foto angezeigt wird, und führt basierend auf diesem Zustand Maßnahmen aus. Wenn kein Foto angezeigt wird, wird der sekundäre Ansichtscontroller reduziert, sodass der Masteransichtscontroller angezeigt wird.

Die CollapseSecondViewController Methode wird beim Erweitern des Geteilten Ansichtscontrollers verwendet, um festzustellen, ob Fotos im Stapel vorhanden sind, wenn dies der Fall ist, dass sie wieder auf diese Ansicht reduziert wird.

Wechseln zwischen Ansichtscontrollern

Als Nächstes sehen wir uns an, wie die adaptive Fotos Anwendung zwischen Ansichtscontrollern wechselt. AAPLConversationViewController Wenn der Benutzer eine Zelle aus der Tabelle auswählt, wird die ShowDetailViewController Methode aufgerufen, um die Detailansicht anzuzeigen:

public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
    var photo = PhotoForIndexPath (indexPath);
    var controller = new AAPLPhotoViewController ();
    controller.Photo = photo;

    int photoNumber = indexPath.Row + 1;
    int photoCount = (int)Conversation.Photos.Count;
    controller.Title = string.Format ("{0} of {1}", photoNumber, photoCount);
    ShowDetailViewController (controller, this);
}

Anzeigen von Offenlegungsindikatoren

In der Adaptiven Fotoanwendung gibt es mehrere Orte, an denen Offenlegungsindikatoren ausgeblendet oder basierend auf Änderungen an der Trait-Umgebung angezeigt werden. Dies wird mit dem folgenden Code behandelt:

public bool Aapl_willShowingViewControllerPushWithSender ()
{
    var selector = new Selector ("Aapl_willShowingViewControllerPushWithSender");
    var target = this.GetTargetViewControllerForAction (selector, this);

    if (target != null) {
        var type = target.GetType ();
        MethodInfo method = type.GetMethod ("Aapl_willShowingDetailViewControllerPushWithSender");
        return (bool)method.Invoke (target, new object[] { });
    } else {
        return false;
    }
}

public bool Aapl_willShowingDetailViewControllerPushWithSender ()
{
    var selector = new Selector ("Aapl_willShowingDetailViewControllerPushWithSender");
    var target = this.GetTargetViewControllerForAction (selector, this);

    if (target != null) {
        var type = target.GetType ();
        MethodInfo method = type.GetMethod ("Aapl_willShowingDetailViewControllerPushWithSender");
        return (bool)method.Invoke (target, new object[] { });
    } else {
        return false;
    }
}

Diese werden mithilfe der GetTargetViewControllerForAction oben beschriebenen Methode implementiert.

Wenn ein Tabellenansichtscontroller Daten anzeigt, verwendet er die oben implementierten Methoden, um festzustellen, ob ein Push ausgeführt wird, und ob der Offenlegungsindikator entsprechend angezeigt oder ausgeblendet werden soll:

public override void WillDisplay (UITableView tableView, UITableViewCell cell, NSIndexPath indexPath)
{
    bool pushes = ShouldShowConversationViewForIndexPath (indexPath) ?
         Aapl_willShowingViewControllerPushWithSender () :
         Aapl_willShowingDetailViewControllerPushWithSender ();

    cell.Accessory = pushes ? UITableViewCellAccessory.DisclosureIndicator : UITableViewCellAccessory.None;
    var conversation = ConversationForIndexPath (indexPath);
    cell.TextLabel.Text = conversation.Name;
}

Neuer ShowDetailTargetDidChangeNotification Typ

Apple hat einen neuen Benachrichtigungstyp für die Arbeit mit Größenklassen und Trait-Umgebungen aus einem Split View Controller ShowDetailTargetDidChangeNotificationhinzugefügt. Diese Benachrichtigung wird gesendet, wenn die Zieldetailseite für einen Split View Controller geändert wird, z. B. wenn der Controller erweitert oder reduziert wird.

Die Adaptive Fotos-Anwendung verwendet diese Benachrichtigung, um den Status des Offenlegungsindikators zu aktualisieren, wenn sich der Detailansichtscontroller ändert:

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();
    TableView.RegisterClassForCellReuse (typeof(UITableViewCell), AAPLListTableViewControllerCellIdentifier);
    NSNotificationCenter.DefaultCenter.AddObserver (this, new Selector ("showDetailTargetDidChange:"),
        UIViewController.ShowDetailTargetDidChangeNotification, null);
    ClearsSelectionOnViewWillAppear = false;
}

Sehen Sie sich die Adaptive Fotos-Anwendung genauer an, um alle Möglichkeiten zu sehen, wie Größenklassen, Trait-Sammlungen und Adaptive Ansichtscontroller verwendet werden können, um einfach eine einheitliche Anwendung in Xamarin.iOS zu erstellen.

Einheitliche Storyboards

Neu bei iOS 8 ermöglichen Unified Storyboards dem Entwickler das Erstellen einer einheitlichen Storyboarddatei, die auf i Telefon- und iPad-Geräten angezeigt werden kann, indem mehrere Größenklassen verwendet werden. Mithilfe von Unified Storyboards schreibt der Entwickler weniger benutzeroberflächenspezifischen Code und verfügt nur über ein Schnittstellendesign zum Erstellen und Standard.

Die wichtigsten Vorteile von Unified Storyboards sind:

  • Verwenden Sie dieselbe Storyboarddatei für i Telefon und iPad.
  • Stellen Sie rückwärts in iOS 6 und iOS 7 bereit.
  • Zeigen Sie eine Vorschau des Layouts für verschiedene Geräte, Ausrichtungen und Betriebssystemversionen an.

Aktivieren von Größenklassen

Standardmäßig verwendet jedes neue Xamarin.iOS-Projekt Größenklassen. Um Größenklassen und adaptive Segues innerhalb eines Storyboards aus einem älteren Projekt zu verwenden, muss sie zuerst in das Xcode 6 Unified Storyboard-Format konvertiert werden, und das Kontrollkästchen "Größenklassen verwenden" ist im Xcode-Dateiinspektor für Ihre Storyboards aktiviert.

Dynamische Startbildschirme

Die Startbildschirmdatei wird als Begrüßungsbildschirm angezeigt, während eine iOS-Anwendung gestartet wird, um dem Benutzer Feedback zu geben, dass die App tatsächlich gestartet wird. Vor iOS 8 müsste der Entwickler mehrere Default.png Bildressourcen für jeden Gerätetyp, jede Ausrichtung und Bildschirmauflösung einschließen, auf der die Anwendung ausgeführt würde. Beispiel: Default@2x.png, , Default-Landscape@2x~ipad.png, Default-Portrait@2x~ipad.pngusw.

Um die neuen i Telefon 6- und i Telefon 6 Plus-Geräte (und die bevorstehende Apple Watch) mit allen vorhandenen i Telefon- und iPad-Geräten zu berücksichtigen, stellt dies ein großes Array unterschiedlicher Größen, Ausrichtungen und Auflösungen von Default.png Bildressourcen des Startbildschirms dar, die erstellt und Standard enthalten sein müssen. Darüber hinaus können diese Dateien ziemlich groß sein und das Lieferumfangs-Anwendungsbundle "aufblähen", wodurch die Zeit erhöht wird, die zum Herunterladen der Anwendung aus dem iTunes App Store erforderlich ist (möglicherweise, damit sie über ein Mobilfunknetz übermittelt werden kann) und die Menge an Speicherplatz erhöht wird, der auf dem Gerät des Endbenutzers erforderlich ist.

Neu bei iOS 8 kann der Entwickler eine einzelne Atomdatei .xib in Xcode erstellen, die Autolayout- und Größenklassen verwendet, um einen dynamischen Startbildschirm zu erstellen, der für jedes Gerät, jede Auflösung und Ausrichtung funktioniert. Dies reduziert nicht nur die Menge an Arbeit, die der Entwickler benötigt, um alle erforderlichen Imageressourcen zu erstellen und zu Standard, sondern reduziert erheblich die Größe des installierten Bündels der Anwendung.

Dynamische Startbildschirme haben die folgenden Einschränkungen und Überlegungen:

  • Verwenden Sie nur UIKit Klassen.
  • Verwenden Sie eine einzelne Stammansicht, die ein UIView oder UIViewController ein Objekt ist.
  • Nehmen Sie keine Verbindungen mit dem Code der Anwendung vor (fügen Sie keine Aktionen oder Outlets hinzu).
  • Fügen Sie keine Objekte hinzu UIWebView .
  • Verwenden Sie keine benutzerdefinierten Klassen.
  • Verwenden Sie keine Laufzeitattribute.

Betrachten wir mit den oben genannten Richtlinien das Hinzufügen eines dynamischen Startbildschirms zu einem vorhandenen Xamarin iOS 8-Projekt.

Gehen Sie folgendermaßen vor:

  1. Öffnen Sie Visual Studio für Mac, und laden Sie die Projektmappe, um den Dynamischen Startbildschirm hinzuzufügen.

  2. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf die MainStoryboard.storyboard Datei, und wählen Sie "Mit>Xcode-Schnittstellen-Generator öffnen" aus:

    Mit Xcode-Schnittstellen-Generator öffnen

  3. Wählen Sie in Xcode "Neue>>Datei" aus...:

    Datei /Neu auswählen

  4. Wählen Sie den Startbildschirm der iOS-Benutzeroberfläche>>aus, und klicken Sie auf die Schaltfläche "Weiter":

    iOS / Benutzeroberfläche auswählen / Startbildschirm

  5. Benennen Sie die Datei LaunchScreen.xib , und klicken Sie auf die Schaltfläche "Erstellen ":

    Benennen der Datei LaunchScreen.xib

  6. Bearbeiten Sie den Entwurf des Startbildschirms, indem Sie Grafikelemente hinzufügen und Layouteinschränkungen verwenden, um sie für die angegebenen Geräte, Ausrichtungen und Bildschirmgrößen zu positionieren:

    Bearbeiten des Entwurfs des Startbildschirms

  7. Speichern Sie die Änderungen in LaunchScreen.xib.

  8. Wählen Sie das Anwendungsziel und die Registerkarte "Allgemein " aus:

    Wählen Sie das Anwendungsziel und die Registerkarte

  9. Klicken Sie auf die Schaltfläche "Info.plist auswählen", wählen Sie die Info.plist Xamarin-App aus, und klicken Sie auf die Schaltfläche "Auswählen ":

    Wählen Sie die Info.plist für die Xamarin-App aus.

  10. Öffnen Sie im Abschnitt "App-Symbole" und "Bilder starten" das Dropdownmenü "Startbildschirmdatei ", und wählen Sie die LaunchScreen.xib oben erstellte Datei aus:

    Wählen Sie

  11. Speichern Sie die Änderungen an der Datei, und kehren Sie zu Visual Studio für Mac zurück.

  12. Warten Sie, bis Visual Studio für Mac die Synchronisierung von Änderungen mit Xcode abgeschlossen hat.

  13. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Ressourcenordner, und wählen Sie "Dateien hinzufügen">aus...:

    Wählen Sie

  14. Wählen Sie die LaunchScreen.xib oben erstellte Datei aus, und klicken Sie auf die Schaltfläche "Öffnen ":

    Wählen Sie die Datei

  15. Erstellen Sie die Anwendung.

Testen des dynamischen Startbildschirms

Wählen Sie in Visual Studio für Mac den i Telefon 4 Netzhautsimulator aus, und führen Sie die Anwendung aus. Der Dynamische Startbildschirm wird im richtigen Format und in der richtigen Ausrichtung angezeigt:

Der dynamische Startbildschirm, der in vertikaler Ausrichtung angezeigt wird

Beenden Sie die Anwendung in Visual Studio für Mac, und wählen Sie ein iPad iOS 8-Gerät aus. Führen Sie die Anwendung aus, und der Startbildschirm wird für dieses Gerät und die Ausrichtung korrekt formatiert:

Der Dynamische Startbildschirm, der in horizontaler Ausrichtung angezeigt wird

Kehren Sie zu Visual Studio für Mac zurück, und beenden Sie die Ausführung der Anwendung.

Arbeiten mit iOS 7

Um die Abwärtskompatibilität mit iOS 7 zu Standard, fügen Sie einfach die üblichen Default.png Bildressourcen wie gewohnt in die iOS 8-Anwendung ein. iOS kehrt zum vorherigen Verhalten zurück und verwendet diese Dateien als Startbildschirm, wenn sie auf einem iOS 7-Gerät ausgeführt werden.

Zusammenfassung

Dieser Artikel hat sich schnell mit größenklassen befasst und wie sie sich auf das Layout auf i Telefon- und iPad-Geräte auswirken. Es wurde erläutert, wie Traits, Trait Environments und Trait Collections mit Größenklassen arbeiten, um einheitliche Schnittstellen zu erstellen. Es hat sich kurz mit adaptiven Ansichtscontrollern befasst und wie sie mit Größenklassen innerhalb von einheitlichen Schnittstellen arbeiten. Es hat sich die Implementierung von Größenklassen und einheitlichen Schnittstellen vollständig aus C#-Code in einer Xamarin iOS 8-Anwendung angesehen.

Schließlich befasste sich dieser Artikel mit den Grundlagen zum Erstellen eines einzelnen dynamischen Startbildschirms, der auf jedem iOS 8-Gerät als Startbildschirm angezeigt wird.