Share via


Arbeiten mit tvOS-Sammlungsansichten in Xamarin

Sammlungsansichten ermöglichen die Anzeige einer Gruppe von Inhalten mithilfe beliebiger Layouts. Mit integrierter Unterstützung ermöglichen sie die einfache Erstellung von rasterähnlichen oder linearen Layouts und unterstützen auch benutzerdefinierte Layouts.

Beispielsammlungsansicht

Die Sammlungsansicht Standard enthält eine Sammlung von Elementen, die sowohl eine Stellvertretung als auch eine Datenquelle verwenden, um Benutzerinteraktionen und den Inhalt der Auflistung bereitzustellen. Da die Sammlungsansicht auf einem Layoutsubsystem basiert, das von der Ansicht selbst unabhängig ist, kann die Darstellung der Daten der Sammlungsansicht problemlos geändert werden.

Informationen zu Sammlungsansichten

Wie bereits erwähnt, verwaltet eine Sammlungsansicht (UICollectionView) eine sortierte Sammlung von Elementen und stellt diese Elemente mit anpassbaren Layouts dar. Auflistungsansichten funktionieren in ähnlicher Weise wie Tabellenansichten (UITableView), außer sie können Layouts verwenden, um Elemente in mehr als nur einer einzigen Spalte darzustellen.

Wenn Sie eine Sammlungsansicht in tvOS verwenden, ist Ihre App dafür verantwortlich, die der Sammlung zugeordneten Daten mithilfe einer Datenquelle (UICollectionViewDataSource) bereitzustellen. Sammlungsansichtsdaten können optional organisiert und in verschiedenen Gruppen (Abschnitte) dargestellt werden.

Die Sammlungsansicht stellt die einzelnen Elemente auf dem Bildschirm mithilfe einer Zelle (UICollectionViewCell) dar, die die Darstellung eines bestimmten Informationsteils aus der Auflistung (z. B. ein Bild und dessen Titel) bereitstellt.

Optional können ergänzende Ansichten zur Präsentation der Sammlungsansicht hinzugefügt werden, um als Kopf- und Fußzeilen für die Abschnitte und Zellen zu fungieren. Das Layout der Sammlungsansicht ist für die Definition der Platzierung dieser Ansichten zusammen mit den einzelnen Zellen verantwortlich.

Die Sammlungsansicht kann mit einer Stellvertretung (UICollectionViewDelegate) auf Benutzerinteraktionen reagieren. Diese Stellvertretung ist auch dafür verantwortlich, zu bestimmen, ob eine bestimmte Zelle den Fokus erhalten kann, wenn eine Zelle hervorgehoben wurde oder ob eine ausgewählt wurde. In einigen Fällen bestimmt die Stellvertretung die Größe der einzelnen Zellen.

Layouts der Sammlungsansicht

Ein wichtiges Feature einer Sammlungsansicht ist die Trennung zwischen den daten, die sie präsentiert, und dem Layout. Ein Sammlungsansichtslayout (UICollectionViewLayout) ist für die Bereitstellung der Organisation und der Position der Zellen (und aller ergänzenden Ansichten) in der Bildschirmpräsentation der Sammlungsansicht verantwortlich.

Die einzelnen Zellen werden von der Sammlungsansicht aus der angefügten Datenquelle erstellt und dann vom angegebenen Sammlungsansichtslayout angeordnet und angezeigt.

Das Sammlungsansichtslayout wird normalerweise bereitgestellt, wenn die Sammlungsansicht erstellt wird. Sie können das Layout der Sammlungsansicht jedoch jederzeit ändern, und die Bildschirmpräsentation der Daten der Sammlungsansicht wird automatisch mithilfe des bereitgestellten neuen Layouts aktualisiert.

Das Auflistungsansichtslayout bietet mehrere Methoden, mit denen der Übergang zwischen zwei verschiedenen Layouts animiert werden kann (standardmäßig wird keine Animation ausgeführt). Darüber hinaus können Layouts der Sammlungsansicht mit Gestenerkennungen verwendet werden, um die Benutzerinteraktion weiter zu animieren, die zu einer Änderung des Layouts führt.

Erstellen von Zellen und ergänzenden Ansichten

Die Datenquelle einer Sammlungsansicht ist nicht nur für die Bereitstellung der Daten verantwortlich, die das Element der Sammlung sichern, sondern auch für die Zellen, die zum Anzeigen des Inhalts verwendet werden.

Da Sammlungsansichten für die Verarbeitung großer Auflistungen von Elementen entwickelt wurden, können die einzelnen Zellen dequeuiert und wiederverwendet werden, um die Speicherbeschränkungen zu überlaufen. Es gibt zwei verschiedene Methoden für die Dequeueing-Ansichten:

  • DequeueReusableCell - Erstellt oder gibt eine Zelle des angegebenen Typs zurück (wie im Storyboard der App angegeben).
  • DequeueReusableSupplementaryView – Erstellt oder gibt eine ergänzende Ansicht des angegebenen Typs zurück (wie im Storyboard der App angegeben).

Bevor Sie eine dieser Methoden aufrufen, müssen Sie die Klasse, das Storyboard oder .xib die Datei registrieren, die zum Erstellen der Zellenansicht mit der Sammlungsansicht verwendet wird. Zum Beispiel:

public CityCollectionView (IntPtr handle) : base (handle)
{
    // Initialize
    RegisterClassForCell (typeof(CityCollectionViewCell), CityViewDatasource.CardCellId);
    ...
}

Wo typeof(CityCollectionViewCell) stellt die Klasse bereit, die die Ansicht unterstützt, und CityViewDatasource.CardCellId stellt die ID bereit, die verwendet wird, wenn die Zelle (oder Ansicht) dequeuiert wird.

Nachdem die Zelle aufgehoben wurde, konfigurieren Sie sie mit den Daten für das Element, das es darstellt, und kehren zur Anzeige in die Sammlungsansicht zurück.

Informationen zu Sammlungsansichtscontrollern

Ein Sammlungsansichtscontroller (UICollectionViewController) ist ein spezieller Ansichtscontroller (UIViewController), der das folgende Verhalten bereitstellt:

  • Sie ist dafür verantwortlich, die Sammlungsansicht aus dem Storyboard oder .xib der Datei zu laden und die Ansicht zu instanziieren. Wenn sie im Code erstellt wird, wird automatisch eine neue, nicht konfigurierte Sammlungsansicht erstellt.
  • Sobald die Sammlungsansicht geladen wurde, versucht der Controller, seine Datenquelle und Stellvertretung aus dem Storyboard oder .xib der Datei zu laden. Wenn keine verfügbar ist, wird sie als Quelle für beide festgelegt.
  • Stellt sicher, dass die Daten geladen werden, bevor die Sammlungsansicht bei der ersten Anzeige aufgefüllt wird, und lädt die Auswahl auf jeder nachfolgenden Anzeige neu und löscht sie.

Darüber hinaus stellt der Sammlungsansichtscontroller überschriebene Methoden bereit, die zum Verwalten des Lebenszyklus der Sammlungsansicht verwendet werden können, AwakeFromNib z. B. und ViewWillDisplay.

Sammlungsansichten und Storyboards

Die einfachste Möglichkeit zum Arbeiten mit einer Sammlungsansicht in Ihrer Xamarin.tvOS-App besteht darin, eins zum Storyboard hinzuzufügen. Als schnelles Beispiel erstellen wir eine Beispiel-App, die ein Bild, einen Titel und eine Auswahlschaltfläche darstellt. Wenn der Benutzer auf die Schaltfläche "Auswählen" klickt, wird eine Sammlungsansicht angezeigt, mit der der Benutzer ein neues Bild auswählen kann. Wenn ein Bild ausgewählt wird, wird die Sammlungsansicht geschlossen, und das neue Bild und der Titel werden angezeigt.

Gehen wir wie folgt vor:

  1. Starten Sie eine neue Single View tvOS-App in Visual Studio für Mac.

  2. Doppelklicken Sie im Projektmappen-Explorer auf die Main.storyboard Datei, und öffnen Sie sie im iOS-Designer.

  3. Fügen Sie der vorhandenen Ansicht eine Bildansicht, eine Beschriftung und eine Schaltfläche hinzu, und konfigurieren Sie sie so, dass sie wie folgt aussehen:

    Beispiellayout

  4. Weisen Sie der Bildansicht und der Beschriftung auf der Registerkarte "Widget" des Eigenschaften-Explorers einen Namen zu. Zum Beispiel:

    Festlegen des Namens

  5. Ziehen Sie als Nächstes einen Sammlungsansichtscontroller auf das Storyboard:

    Ein Sammlungsansichtscontroller

  6. Ctrl-Drag from the Button to the Collection View Controller and select Push from the popup:

    Wählen Sie

  7. Wenn die App ausgeführt wird, wird die Sammlungsansicht immer dann angezeigt, wenn der Benutzer auf die Schaltfläche klickt.

  8. Wählen Sie die Sammlungsansicht aus, und geben Sie die folgenden Werte auf der Registerkarte "Layout" des Eigenschaften-Explorers ein:

    Der Eigenschaften-Explorer

  9. Dadurch wird die Größe der einzelnen Zellen und der Rahmen zwischen den Zellen und dem äußeren Rand der Auflistungsansicht gesteuert.

  10. Wählen Sie den Sammlungsansichtscontroller aus, und legen Sie dessen Klasse CityCollectionViewController auf der Registerkarte "Widget" fest:

    Festlegen der Klasse auf CityCollectionViewController

  11. Wählen Sie die Sammlungsansicht aus, und legen Sie ihre Klasse auf der Registerkarte "Widget" festCityCollectionView:

    Festlegen der Klasse auf

  12. Wählen Sie die Sammlungsansichtszelle aus, und legen Sie ihre Klasse auf der Registerkarte "Widget" festCityCollectionViewCell:

    Festlegen der Klasse auf CityCollectionViewCell

  13. Stellen Sie auf der Registerkarte "Widget" sicher, dass das Layout und Flow die Bildlaufrichtung für die Sammlungsansicht gilt Vertical :

    Die Registerkarte

  14. Wählen Sie die Sammlungsansichtszelle aus, und legen Sie dessen Identität CityCell auf der Registerkarte "Widget" fest:

    Festlegen der Identität auf

  15. Speichern Sie die Änderungen.

Wenn wir das Layout der Sammlungsansicht ausgewählt Custom haben, könnten wir ein benutzerdefiniertes Layout angegeben haben. Apple bietet ein integriertes UICollectionViewFlowLayout Layout, UICollectionViewDelegateFlowLayout das Daten in einem rasterbasierten Layout problemlos darstellen kann (diese werden vom flow Layoutstil verwendet).

Weitere Informationen zum Arbeiten mit Storyboards finden Sie in unserem Schnellstarthandbuch für Hello, tvOS.

Bereitstellen von Daten für die Sammlungsansicht

Nachdem wir nun unseren Sammlungsansichts-Controller (und den Sammlungsansichtscontroller) zu unserem Storyboard hinzugefügt haben, müssen wir die Daten für die Sammlung bereitstellen.

Das Datenmodell

Zunächst erstellen wir ein Modell für unsere Daten, das den Dateinamen für das anzuzeigende Bild, den Titel und eine Kennzeichnung enthält, damit die Stadt ausgewählt werden kann.

Erstellen Sie eine CityInfo Klasse, und sehen Sie wie folgt aus:

using System;

namespace tvCollection
{
    public class CityInfo
    {
        #region Computed Properties
        public string ImageFilename { get; set; }
        public string Title { get; set; }
        public bool CanSelect{ get; set; }
        #endregion

        #region Constructors
        public CityInfo (string filename, string title, bool canSelect)
        {
            // Initialize
            this.ImageFilename = filename;
            this.Title = title;
            this.CanSelect = canSelect;
        }
        #endregion
    }
}

Die Sammlungsansichtszelle

Jetzt müssen wir definieren, wie die Daten für jede Zelle dargestellt werden. Bearbeiten Sie die CityCollectionViewCell.cs Datei (die automatisch aus Ihrer Storyboarddatei erstellt wurde), und sehen Sie wie folgt aus:

using System;
using Foundation;
using UIKit;
using CoreGraphics;

namespace tvCollection
{
    public partial class CityCollectionViewCell : UICollectionViewCell
    {
        #region Private Variables
        private CityInfo _city;
        #endregion

        #region Computed Properties
        public UIImageView CityView { get ; set; }
        public UILabel CityTitle { get; set; }

        public CityInfo City {
            get { return _city; }
            set {
                _city = value;
                CityView.Image = UIImage.FromFile (City.ImageFilename);
                CityView.Alpha = (City.CanSelect) ? 1.0f : 0.5f;
                CityTitle.Text = City.Title;
            }
        }
        #endregion

        #region Constructors
        public CityCollectionViewCell (IntPtr handle) : base (handle)
        {
            // Initialize
            CityView = new UIImageView(new CGRect(22, 19, 320, 171));
            CityView.AdjustsImageWhenAncestorFocused = true;
            AddSubview (CityView);

            CityTitle = new UILabel (new CGRect (22, 209, 320, 21)) {
                TextAlignment = UITextAlignment.Center,
                TextColor = UIColor.White,
                Alpha = 0.0f
            };
            AddSubview (CityTitle);
        }
        #endregion


    }
}

Für unsere tvOS-App zeigen wir ein Bild und einen optionalen Titel an. Wenn die angegebene Stadt nicht ausgewählt werden kann, wird die Bildansicht mithilfe des folgenden Codes abgeblendet:

CityView.Alpha = (City.CanSelect) ? 1.0f : 0.5f;

Wenn die Zelle, die das Bild enthält, vom Benutzer in den Fokus gestellt wird, möchten wir den integrierten Parallax-Effekt verwenden, um die folgende Eigenschaft festzulegen:

CityView.AdjustsImageWhenAncestorFocused = true;

Weitere Informationen zu Navigation und Fokus finden Sie in der Dokumentation "Arbeiten mit Navigation und Fokus " und "Siri Remote- und Bluetooth-Controller ".

Die Sammlungsansicht Datenanbieter

Nachdem unser Datenmodell erstellt und unser Zellenlayout definiert wurde, erstellen wir eine Datenquelle für unsere Sammlungsansicht. Die Datenquelle ist nicht nur für die Bereitstellung der Sicherungsdaten verantwortlich, sondern auch für die Dequeue der Zellen, um die einzelnen Zellen auf dem Bildschirm anzuzeigen.

Erstellen Sie eine CityViewDatasource Klasse, und sehen Sie wie folgt aus:

using System;
using System.Collections.Generic;
using UIKit;
using Foundation;
using CoreGraphics;
using ObjCRuntime;

namespace tvCollection
{
    public class CityViewDatasource : UICollectionViewDataSource
    {
        #region Application Access
        public static AppDelegate App {
            get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
        }
        #endregion

        #region Static Constants
        public static NSString CardCellId = new NSString ("CityCell");
        #endregion

        #region Computed Properties
        public List<CityInfo> Cities { get; set; } = new List<CityInfo>();
        public CityCollectionView ViewController { get; set; }
        #endregion

        #region Constructors
        public CityViewDatasource (CityCollectionView controller)
        {
            // Initialize
            this.ViewController = controller;
            PopulateCities ();
        }
        #endregion

        #region Public Methods
        public void PopulateCities() {

            // Clear existing cities
            Cities.Clear();

            // Add new cities
            Cities.Add(new CityInfo("City01.jpg", "Houses by Water", false));
            Cities.Add(new CityInfo("City02.jpg", "Turning Circle", true));
            Cities.Add(new CityInfo("City03.jpg", "Skyline at Night", true));
            Cities.Add(new CityInfo("City04.jpg", "Golden Gate Bridge", true));
            Cities.Add(new CityInfo("City05.jpg", "Roads by Night", true));
            Cities.Add(new CityInfo("City06.jpg", "Church Domes", true));
            Cities.Add(new CityInfo("City07.jpg", "Mountain Lights", true));
            Cities.Add(new CityInfo("City08.jpg", "City Scene", false));
            Cities.Add(new CityInfo("City09.jpg", "House in Winter", true));
            Cities.Add(new CityInfo("City10.jpg", "By the Lake", true));
            Cities.Add(new CityInfo("City11.jpg", "At the Dome", true));
            Cities.Add(new CityInfo("City12.jpg", "Cityscape", true));
            Cities.Add(new CityInfo("City13.jpg", "Model City", true));
            Cities.Add(new CityInfo("City14.jpg", "Taxi, Taxi!", true));
            Cities.Add(new CityInfo("City15.jpg", "On the Sidewalk", true));
            Cities.Add(new CityInfo("City16.jpg", "Midnight Walk", true));
            Cities.Add(new CityInfo("City17.jpg", "Lunchtime Cafe", true));
            Cities.Add(new CityInfo("City18.jpg", "Coffee Shop", true));
            Cities.Add(new CityInfo("City19.jpg", "Rustic Tavern", true));
        }
        #endregion

        #region Override Methods
        public override nint NumberOfSections (UICollectionView collectionView)
        {
            return 1;
        }

        public override nint GetItemsCount (UICollectionView collectionView, nint section)
        {
            return Cities.Count;
        }

        public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath)
        {
            var cityCell = (CityCollectionViewCell)collectionView.DequeueReusableCell (CardCellId, indexPath);
            var city = Cities [indexPath.Row];

            // Initialize city
            cityCell.City = city;

            return cityCell;
        }
        #endregion
    }
}

Lassen Sie uns diese Klasse im Detail betrachten. Zunächst erben wir von UICollectionViewDataSource der Zellen-ID und stellen eine Verknüpfung mit der Zellen-ID bereit (die wir im iOS-Designer zugewiesen haben):

public static NSString CardCellId = new NSString ("CityCell");

Als Nächstes stellen wir Speicher für unsere Sammlungsdaten bereit und stellen eine Klasse zum Auffüllen der Daten bereit:

public List<CityInfo> Cities { get; set; } = new List<CityInfo>();
...

public void PopulateCities() {

    // Clear existing cities
    Cities.Clear();

    // Add new cities
    Cities.Add(new CityInfo("City01.jpg", "Houses by Water", false));
    Cities.Add(new CityInfo("City02.jpg", "Turning Circle", true));
    ...
}

Anschließend überschreiben wir die NumberOfSections Methode und geben die Anzahl der Abschnitte (Gruppen von Elementen) zurück, die unsere Sammlungsansicht aufweist. In diesem Fall gibt es nur eine:

public override nint NumberOfSections (UICollectionView collectionView)
{
    return 1;
}

Als Nächstes geben wir die Anzahl der Elemente in unserer Sammlung mithilfe des folgenden Codes zurück:

public override nint GetItemsCount (UICollectionView collectionView, nint section)
{
    return Cities.Count;
}

Schließlich dequeue wir eine wiederverwendbare Zelle, wenn die Sammlungsansichtsanforderung mit dem folgenden Code lautet:

public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath)
{
    var cityCell = (CityCollectionViewCell)collectionView.DequeueReusableCell (CardCellId, indexPath);
    var city = Cities [indexPath.Row];

    // Initialize city
    cityCell.City = city;

    return cityCell;
}

Nachdem wir eine Sammlungsansichtszelle unseres CityCollectionViewCell Typs erhalten haben, füllen wir sie mit dem angegebenen Element auf.

Reagieren auf Benutzerereignisse

Da wir möchten, dass der Benutzer ein Element aus unserer Sammlung auswählen kann, müssen wir eine Sammlungsansichtsdelegat bereitstellen, um diese Interaktion zu verarbeiten. Und wir müssen eine Möglichkeit bieten, unsere Anrufansicht darüber zu informieren, welches Element der Benutzer ausgewählt hat.

Die App-Stellvertretung

Wir benötigen eine Möglichkeit, das aktuell ausgewählte Element aus der Sammlungsansicht zurück zur aufrufenden Ansicht zu verknüpfen. Wir verwenden eine benutzerdefinierte Eigenschaft auf unserer AppDelegate. Bearbeiten Sie die AppDelegate.cs Datei, und fügen Sie den folgenden Code hinzu:

public CityInfo SelectedCity { get; set;} = new CityInfo("City02.jpg", "Turning Circle", true);

Dadurch wird die Eigenschaft definiert und die Standardstadt festgelegt, die anfänglich angezeigt wird. Später verwenden wir diese Eigenschaft, um die Auswahl des Benutzers anzuzeigen und die Auswahl zuzulassen.

Der Sammlungsansichtsdelegat

Fügen Sie als Nächstes dem Projekt eine neue CityViewDelegate Klasse hinzu, und sehen Sie wie folgt aus:

using System;
using System.Collections.Generic;
using UIKit;
using Foundation;
using CoreGraphics;

namespace tvCollection
{
    public class CityViewDelegate : UICollectionViewDelegateFlowLayout
    {
        #region Application Access
        public static AppDelegate App {
            get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
        }
        #endregion

        #region Constructors
        public CityViewDelegate ()
        {
        }
        #endregion

        #region Override Methods
        public override CGSize GetSizeForItem (UICollectionView collectionView, UICollectionViewLayout layout, NSIndexPath indexPath)
        {
            return new CGSize (361, 256);
        }

        public override bool CanFocusItem (UICollectionView collectionView, NSIndexPath indexPath)
        {
            if (indexPath == null) {
                return false;
            } else {
                var controller = collectionView as CityCollectionView;
                return controller.Source.Cities[indexPath.Row].CanSelect;
            }
        }

        public override void ItemSelected (UICollectionView collectionView, NSIndexPath indexPath)
        {
            var controller = collectionView as CityCollectionView;
            App.SelectedCity = controller.Source.Cities [indexPath.Row];

            // Close Collection
            controller.ParentController.DismissViewController(true,null);
        }
        #endregion
    }
}

Werfen wir einen genaueren Blick auf diesen Kurs. Zuerst erben wir von UICollectionViewDelegateFlowLayout. Der Grund, warum wir von dieser Klasse erben und nicht, UICollectionViewDelegate dass wir das integrierte Element UICollectionViewFlowLayout verwenden, um unsere Elemente und nicht einen benutzerdefinierten Layouttyp darzustellen.

Als Nächstes geben wir die Größe für die einzelnen Elemente mit diesem Code zurück:

public override CGSize GetSizeForItem (UICollectionView collectionView, UICollectionViewLayout layout, NSIndexPath indexPath)
{
    return new CGSize (361, 256);
}

Anschließend entscheiden wir, ob eine bestimmte Zelle den Fokus mithilfe des folgenden Codes erhalten kann:

public override bool CanFocusItem (UICollectionView collectionView, NSIndexPath indexPath)
{
    if (indexPath == null) {
        return false;
    } else {
        var controller = collectionView as CityCollectionView;
        return controller.Source.Cities[indexPath.Row].CanSelect;
    }
}

Wir überprüfen, ob ein bestimmter Teil der Sicherungsdaten sein CanSelect Kennzeichen auf diesen Wert festgelegt true und zurückgegeben hat. Weitere Informationen zu Navigation und Fokus finden Sie in der Dokumentation "Arbeiten mit Navigation und Fokus " und "Siri Remote- und Bluetooth-Controller ".

Schließlich antworten wir auf den Benutzer, der ein Element mit dem folgenden Code auswählt:

public override void ItemSelected (UICollectionView collectionView, NSIndexPath indexPath)
{
    var controller = collectionView as CityCollectionView;
    App.SelectedCity = controller.Source.Cities [indexPath.Row];

    // Close Collection
    controller.ParentController.DismissViewController(true,null);
}

Hier legen wir die SelectedCity Eigenschaft unseres AppDelegate Elements auf das Element fest, das der Benutzer ausgewählt hat, und wir schließen den Sammlungsansichtscontroller und kehren zur Ansicht zurück, die uns aufgerufen hat. Wir haben die ParentController Eigenschaft unserer Sammlungsansicht noch nicht definiert, wir werden dies als Nächstes tun.

Konfigurieren der Sammlungsansicht

Jetzt müssen wir unsere Sammlungsansicht bearbeiten und unsere Datenquelle und Stellvertretung zuweisen. Bearbeiten Sie die CityCollectionView.cs Datei (die für uns automatisch aus unserem Storyboard erstellt wurde), und stellen Sie sicher, dass sie wie folgt aussieht:

using System;
using Foundation;
using UIKit;

namespace tvCollection
{
    public partial class CityCollectionView : UICollectionView
    {
        #region Application Access
        public static AppDelegate App {
            get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
        }
        #endregion

        #region Computed Properties
        public CityViewDatasource Source {
            get { return DataSource as CityViewDatasource;}
        }

        public CityCollectionViewController ParentController { get; set;}
        #endregion

        #region Constructors
        public CityCollectionView (IntPtr handle) : base (handle)
        {
            // Initialize
            RegisterClassForCell (typeof(CityCollectionViewCell), CityViewDatasource.CardCellId);
            DataSource = new CityViewDatasource (this);
            Delegate = new CityViewDelegate ();
        }
        #endregion

        #region Override Methods
        public override nint NumberOfSections ()
        {
            return 1;
        }

        public override void DidUpdateFocus (UIFocusUpdateContext context, UIFocusAnimationCoordinator coordinator)
        {
            var previousItem = context.PreviouslyFocusedView as CityCollectionViewCell;
            if (previousItem != null) {
                Animate (0.2, () => {
                    previousItem.CityTitle.Alpha = 0.0f;
                });
            }

            var nextItem = context.NextFocusedView as CityCollectionViewCell;
            if (nextItem != null) {
                Animate (0.2, () => {
                    nextItem.CityTitle.Alpha = 1.0f;
                });
            }
        }
        #endregion
    }
}

Zunächst bieten wir eine Verknüpfung für den Zugriff auf unsere:AppDelegate

public static AppDelegate App {
    get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
}

Als Nächstes stellen wir eine Verknüpfung zur Datenquelle der Sammlungsansicht und einer Eigenschaft für den Zugriff auf den Sammlungsansichtscontroller bereit (wird von unserer Stellvertretung oben verwendet, um die Sammlung zu schließen, wenn der Benutzer eine Auswahl trifft):

public CityViewDatasource Source {
    get { return DataSource as CityViewDatasource;}
}

public CityCollectionViewController ParentController { get; set;}

Anschließend verwenden wir den folgenden Code, um die Sammlungsansicht zu initialisieren und unsere Zellenklasse, Datenquelle und Stellvertretung zuzuweisen:

public CityCollectionView (IntPtr handle) : base (handle)
{
    // Initialize
    RegisterClassForCell (typeof(CityCollectionViewCell), CityViewDatasource.CardCellId);
    DataSource = new CityViewDatasource (this);
    Delegate = new CityViewDelegate ();
}

Schließlich soll der Titel unter dem Bild nur sichtbar sein, wenn der Benutzer ihn hervorgehoben hat (im Fokus). Dazu verwenden wir den folgenden Code:

public override void DidUpdateFocus (UIFocusUpdateContext context, UIFocusAnimationCoordinator coordinator)
{
    var previousItem = context.PreviouslyFocusedView as CityCollectionViewCell;
    if (previousItem != null) {
        Animate (0.2, () => {
            previousItem.CityTitle.Alpha = 0.0f;
        });
    }

    var nextItem = context.NextFocusedView as CityCollectionViewCell;
    if (nextItem != null) {
        Animate (0.2, () => {
            nextItem.CityTitle.Alpha = 1.0f;
        });
    }
}

Wir legen die Transparenz des vorherigen Elements fest, das den Fokus auf Null (0) verliert, und die Transparenz des nächsten Elements erhält den Fokus auf 100 %. Dieser Übergang wird ebenfalls animiert.

Konfigurieren des Sammlungsansichtscontrollers

Jetzt müssen wir die endgültige Konfiguration in unserer Sammlungsansicht ausführen und dem Controller erlauben, die eigenschaft festzulegen, die wir definiert haben, damit die Sammlungsansicht geschlossen werden kann, nachdem der Benutzer eine Auswahl getroffen hat.

Bearbeiten Sie die CityCollectionViewController.cs Datei (automatisch aus unserem Storyboard erstellt) und sehen Sie wie folgt aus:

// This file has been autogenerated from a class added in the UI designer.

using System;

using Foundation;
using UIKit;

namespace tvCollection
{
    public partial class CityCollectionViewController : UICollectionViewController
    {
        #region Computed Properties
        public CityCollectionView Collection {
            get { return CollectionView as CityCollectionView; }
        }
        #endregion

        #region Constructors
        public CityCollectionViewController (IntPtr handle) : base (handle)
        {
        }
        #endregion

        #region Override Methods
        public override void AwakeFromNib ()
        {
            base.AwakeFromNib ();

            // Save link to controller
            Collection.ParentController = this;
        }
        #endregion
    }
}

Zusammenfassung

Nachdem wir nun alle Teile zusammengestellt haben, um unsere Sammlungsansicht aufzufüllen und zu steuern, müssen wir die endgültigen Änderungen an unserer Standard Ansicht vornehmen, um alles zusammenzuführen.

Bearbeiten Sie die ViewController.cs Datei (automatisch aus unserem Storyboard erstellt) und sehen Sie wie folgt aus:

using System;
using Foundation;
using UIKit;
using tvCollection;

namespace MySingleView
{
    public partial class ViewController : UIViewController
    {
        #region Application Access
        public static AppDelegate App {
            get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
        }
        #endregion

        #region Constructors
        public ViewController (IntPtr handle) : base (handle)
        {
        }
        #endregion

        #region Override Methods
        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();
            // Perform any additional setup after loading the view, typically from a nib.
        }

        public override void ViewWillAppear (bool animated)
        {
            base.ViewWillAppear (animated);

            // Update image with the currently selected one
            CityView.Image = UIImage.FromFile(App.SelectedCity.ImageFilename);
            BackgroundView.Image = CityView.Image;
            CityTitle.Text = App.SelectedCity.Title;
        }

        public override void DidReceiveMemoryWarning ()
        {
            base.DidReceiveMemoryWarning ();
            // Release any cached data, images, etc that aren't in use.
        }
        #endregion
    }
}

Der folgende Code zeigt zunächst das ausgewählte Element aus der SelectedCity Eigenschaft der AppDelegate Auflistung an und zeigt es erneut an, wenn der Benutzer eine Auswahl aus der Sammlungsansicht getroffen hat:

public override void ViewWillAppear (bool animated)
{
    base.ViewWillAppear (animated);

    // Update image with the currently selected one
    CityView.Image = UIImage.FromFile(App.SelectedCity.ImageFilename);
    BackgroundView.Image = CityView.Image;
    CityTitle.Text = App.SelectedCity.Title;
}

Testen der App

Wenn Sie die App erstellen und ausführen, wird die Standard Ansicht mit der Standardstadt angezeigt:

Der bildschirm

Wenn der Benutzer auf die Schaltfläche "Ansicht auswählen" klickt, wird die Sammlungsansicht angezeigt:

Die Sammlungsansicht

Jede Stadt, für false die die CanSelect Eigenschaft festgelegt ist, wird abgeblendet angezeigt, und der Benutzer kann den Fokus nicht darauf setzen. Wenn der Benutzer ein Element hervorhebt (machen Sie es im Fokus), wird der Titel angezeigt, und er kann den Parallax-Effekt verwenden, um das Bild in 3D subtil zu kippen.

Wenn der Benutzer auf ein ausgewähltes Bild klickt, wird die Sammlungsansicht geschlossen, und die Standard Ansicht wird mit dem neuen Bild erneut angezeigt:

Ein neues Bild auf dem Startbildschirm

Erstellen von benutzerdefinierten Layouts und Neuanordnen von Elementen

Eines der wichtigsten Features der Verwendung einer Sammlungsansicht ist die Möglichkeit, benutzerdefinierte Layouts zu erstellen. Da tvOS von iOS erbt, ist der Prozess zum Erstellen eines benutzerdefinierten Layouts identisch. Weitere Informationen finden Sie in der Dokumentation "Einführung in Sammlungsansichten ".

Kürzlich zu Sammlungsansichten für iOS 9 hinzugefügt wurde, war die Möglichkeit, die Neuanordnung von Elementen in der Auflistung einfach zu ermöglichen. Da tvOS 9 eine Teilmenge von iOS 9 ist, geschieht dies auf die gleiche Weise. Weitere Details finden Sie im Dokument "Änderungen der Sammlungsansicht ".

Zusammenfassung

Dieser Artikel befasst sich mit dem Entwerfen und Arbeiten mit Sammlungsansichten innerhalb einer Xamarin.tvOS-App. Zunächst wurden alle Elemente erörtert, aus denen die Sammlungsansicht besteht. Als Nächstes wurde gezeigt, wie Sie eine Sammlungsansicht mithilfe eines Storyboards entwerfen und implementieren. Schließlich werden Links zu Informationen zum Erstellen von benutzerdefinierten Layouts und zum Neuanordnen von Elementen bereitgestellt.