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.
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:
Starten Sie eine neue Single View tvOS-App in Visual Studio für Mac.
Doppelklicken Sie im Projektmappen-Explorer auf die
Main.storyboard
Datei, und öffnen Sie sie im iOS-Designer.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:
Weisen Sie der Bildansicht und der Beschriftung auf der Registerkarte "Widget" des Eigenschaften-Explorers einen Namen zu. Zum Beispiel:
Ziehen Sie als Nächstes einen Sammlungsansichtscontroller auf das Storyboard:
Ctrl-Drag from the Button to the Collection View Controller and select Push from the popup:
Wenn die App ausgeführt wird, wird die Sammlungsansicht immer dann angezeigt, wenn der Benutzer auf die Schaltfläche klickt.
Wählen Sie die Sammlungsansicht aus, und geben Sie die folgenden Werte auf der Registerkarte "Layout" des Eigenschaften-Explorers ein:
Dadurch wird die Größe der einzelnen Zellen und der Rahmen zwischen den Zellen und dem äußeren Rand der Auflistungsansicht gesteuert.
Wählen Sie den Sammlungsansichtscontroller aus, und legen Sie dessen Klasse
CityCollectionViewController
auf der Registerkarte "Widget" fest:Wählen Sie die Sammlungsansicht aus, und legen Sie ihre Klasse auf der Registerkarte "Widget" fest
CityCollectionView
:Wählen Sie die Sammlungsansichtszelle aus, und legen Sie ihre Klasse auf der Registerkarte "Widget" fest
CityCollectionViewCell
:Stellen Sie auf der Registerkarte "Widget" sicher, dass das Layout und
Flow
die Bildlaufrichtung für die Sammlungsansicht giltVertical
:Wählen Sie die Sammlungsansichtszelle aus, und legen Sie dessen Identität
CityCell
auf der Registerkarte "Widget" fest: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:
Wenn der Benutzer auf die Schaltfläche "Ansicht auswählen" klickt, wird die Sammlungsansicht angezeigt:
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:
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.