Arbeiten mit tvOS-Tabellenansichten in Xamarin
Dieser Artikel behandelt das Entwerfen und Arbeiten mit Tabellenansichts- und Tabellenansichtscontrollern innerhalb einer Xamarin.tvOS-App.
In tvOS wird eine Tabellenansicht als einzelne Spalte mit Bildlaufzeilen dargestellt, die optional in Gruppen oder Abschnitte unterteilt werden können. Tabellenansichten sollten verwendet werden, wenn Sie eine große Menge an Daten effizient für den Benutzer anzeigen müssen, um sie verständlich zu machen.
Tabellenansichten werden in der Regel auf einer Seite einer geteilten Ansicht als Navigation angezeigt, wobei die Details des ausgewählten Elements auf der gegenüberliegenden Seite angezeigt werden:
Informationen zu Tabellenansichten
A UITableView
displays a single column of scrollable rows as a hierarchical list of information that can optional be organized into groups or sections:
Apple hat die folgenden Vorschläge für das Arbeiten mit Tabellen:
- Achten Sie auf Breite – Versuchen Sie, das richtige Gleichgewicht in den Tabellenbreiten zu treffen. Wenn die Tabelle zu breit ist, kann es schwierig sein, aus einer Entfernung zu scannen und den verfügbaren Inhaltsbereich zu entfernen. Wenn die Tabelle zu schmal ist, kann dies dazu führen, dass die Informationen abgeschnitten oder umgebrochen werden, kann dies für den Benutzer schwierig sein, aus dem gesamten Raum zu lesen.
- Schnelles Anzeigen von Tabelleninhalten – Bei umfangreichen Listen mit Daten laden Sie den Inhalt, und beginnen Sie mit der Anzeige von Informationen, sobald die Tabelle dem Benutzer angezeigt wird. Wenn die Tabelle lange dauert, bis die Tabelle geladen wird, verliert der Benutzer möglicherweise interesse an Ihrer App oder hält sie für gesperrt.
- Informieren Sie den Benutzer über lange Inhaltsladevorgänge – Wenn eine lange Tabellenladezeit unvermeidbar ist, stellen Sie eine Statusanzeige oder einen Aktivitätsindikator vor, damit sie wissen, dass die App nicht gesperrt wurde.
Zellentypen der Tabellenansicht
A UITableViewCell
wird verwendet, um die einzelnen Datenzeilen in der Tabellenansicht darzustellen. Apple hat mehrere Standardmäßige Tabellenzellentypen definiert:
- Standard - Dieser Typ stellt eine Option Bild auf der linken Seite der Zelle und linksbündig ausgerichteten Titel auf der rechten Seite dar.
- Untertitel – Dieser Typ stellt einen linksbündigen Titel in der ersten Zeile und einen kleineren linksbündigen Untertitel in der nächsten Zeile dar.
- Wert 1 – Dieser Typ stellt einen linksbündigen Titel mit einem helleren, rechtsbündigen Untertitel in derselben Zeile dar.
- Wert 2 – Dieser Typ stellt einen rechtsbündigen Titel mit einem helleren, linksbündigen Untertitel in derselben Zeile dar.
Alle Standardmäßigen Tabellenansichtszellentypen unterstützen auch grafische Elemente wie Offenlegungsindikatoren oder Häkchen.
Darüber hinaus können Sie einen benutzerdefinierten Tabellenansicht-Zelltyp definieren und eine Prototypzelle präsentieren, die Sie entweder im Schnittstellen-Designer oder über Code erstellen.
Apple hat die folgenden Vorschläge für die Arbeit mit Tabellenansichtszellen:
- Vermeiden Sie Textausschnitte – Halten Sie die einzelnen Textzeilen kurz, sodass sie nicht abgeschnitten werden. Abgeschnittene Wörter oder Ausdrücke sind für den Benutzer schwer zu analysieren.
- Berücksichtigen Sie den Status "Fokussierte Zeile ": Da eine Zeile größer wird, müssen Sie die Darstellung Ihrer Zelle in allen Zuständen testen, wenn der Fokus mehr abgerundet wird. Bilder oder Text werden möglicherweise abgeschnitten oder sehen im Status "Relevant" falsch aus.
- Sparsame Verwendung bearbeitbarer Tabellen – Das Verschieben oder Löschen von Tabellenzeilen ist bei tvOS zeitaufwändiger als iOS. Sie müssen sorgfältig entscheiden, ob diese Funktion Von Ihrer tvOS-App hinzugefügt oder ablenken wird.
- Erstellen Sie bei Bedarf benutzerdefinierte Zelltypen – Die integrierten Zellenansichtszellentypen eignen sich zwar hervorragend für viele Situationen, erwägen Sie jedoch, benutzerdefinierte Zelltypen für nicht standardmäßige Informationen zu erstellen, um dem Benutzer eine bessere Kontrolle zu bieten und die Informationen besser darzustellen.
Arbeiten mit Tabellenansichten
Die einfachste Möglichkeit zum Arbeiten mit Tabellenansichten in einer Xamarin.tvOS-App besteht darin, ihre Darstellung im Schnittstellen-Designer zu erstellen und zu ändern.
Gehen Sie wie folgt vor, um zu beginnen:
Starten Sie in Visual Studio für Mac ein neues tvOS-App-Projekt, wählen Sie "tvOS>App>Single View App" aus, und klicken Sie auf die Schaltfläche "Weiter":
Geben Sie einen Namen für die App ein, und klicken Sie auf "Weiter":
Passen Sie entweder den Projektnamen und den Projektmappennamen an, oder übernehmen Sie die Standardwerte, und klicken Sie auf die Schaltfläche "Erstellen", um die neue Lösung zu erstellen:
Doppelklicken Sie im Projektmappen-Pad auf die
Main.storyboard
Datei, um sie im iOS-Designer zu öffnen:Wählen Sie den Standardansichtscontroller aus, und löschen Sie diesen:
Wählen Sie einen Geteilten Ansichtscontroller aus der Toolbox aus, und ziehen Sie ihn auf die Entwurfsoberfläche.
Standardmäßig erhalten Sie eine geteilte Ansicht mit einem Navigationsansichtscontroller und einem Tabellenansichtscontroller auf der linken Seite und einem Ansichtscontroller auf der rechten Seite. Dies ist apples vorgeschlagene Verwendung einer Tabellenansicht in tvOS:
Sie müssen jeden Teil der Tabellenansicht auswählen und ihm auf der Registerkarte "Widget" des Eigenschaften-Explorers einen benutzerdefinierten Klassennamen zuweisen, damit Sie später im C#-Code darauf zugreifen können. Beispiel: Der Tabellenansichtscontroller:
Stellen Sie sicher, dass Sie eine benutzerdefinierte Klasse für den Tabellenansichtscontroller, die Tabellenansicht und alle Prototypzellen erstellen. Visual Studio für Mac fügen die benutzerdefinierten Klassen während der Erstellung zur Projektstruktur hinzu:
Wählen Sie als Nächstes die Tabellenansicht in der Entwurfsoberfläche aus, und passen Sie die Eigenschaften nach Bedarf an. Wie z. B. die Anzahl der Prototypzellen und die Formatvorlage (nur oder gruppiert):
Wählen Sie für jede Prototypzelle sie aus, und weisen Sie dem Eigenschaften-Explorer auf der Registerkarte "Widget" einen eindeutigen Bezeichner zu. Dieser Schritt ist sehr wichtig , da Sie diesen Bezeichner später benötigen, wenn Sie die Tabelle auffüllen. Beispiel:
AttrCell
Sie können auch auswählen, dass die Zelle als einer der Standardtabellenansicht-Zelltypen über das Dropdownmenü "Formatvorlage " angezeigt oder auf " Benutzerdefiniert" festgelegt wird, und die Entwurfsoberfläche zum Layout der Zelle verwenden, indem Sie in anderen UI-Widgets aus der Toolbox ziehen:
Weisen Sie jedem UI-Element auf der Registerkarte "Widget" des Eigenschaften-Explorers einen eindeutigen Namen zu, damit Sie später im C#-Code darauf zugreifen können:
Wiederholen Sie den obigen Schritt für alle Prototypzellen in der Tabellenansicht.
Weisen Sie als Nächstes benutzerdefinierte Klassen dem restlichen Ui-Design zu, layouten Sie die Detailansicht, und weisen Sie jedem UI-Element in der Detailansicht eindeutige Namen zu, damit Sie auch in C# darauf zugreifen können. Beispiel:
Speichern Sie Ihre Änderungen im Storyboard.
Entwerfen eines Datenmodells
Um die Arbeit mit den Informationen zu erleichtern, die in der Tabellenansicht angezeigt werden, und um die Darstellung detaillierter Informationen zu vereinfachen (wenn der Benutzer Zeilen in der Tabellenansicht auswählt oder hervorhebung), erstellen Sie eine benutzerdefinierte Klasse oder Klassen, die als Datenmodell für die dargestellten Informationen fungieren.
Nehmen Sie sich das Beispiel einer Reisebuchungs-App mit einer Liste von Städten an, die jeweils eine eindeutige Liste der Sehenswürdigkeiten enthält, die der Benutzer auswählen kann. Der Benutzer kann eine Attraktion als Favorit markieren, auswählen, um Wegbeschreibungen zu einer Attraktion zu erhalten und einen Flug zu einer bestimmten Stadt zu buchen.
Um das Datenmodell für eine Attraktion zu erstellen, klicken Sie im Projektblock mit der rechten Maustaste auf den Projektnamen, und wählen Sie "Neue Datei hinzufügen... aus>" aus. Geben Sie AttractionInformation
den Namen ein, und klicken Sie auf die Schaltfläche "Neu":
Bearbeiten Sie die AttractionInformation.cs
Datei, und stellen Sie sicher, dass sie wie folgt aussieht:
using System;
using Foundation;
namespace tvTable
{
public class AttractionInformation : NSObject
{
#region Computed Properties
public CityInformation City { get; set;}
public string Name { get; set;}
public string Description { get; set;}
public string ImageName { get; set;}
public bool IsFavorite { get; set;}
public bool AddDirections { get; set;}
#endregion
#region Constructors
public AttractionInformation (string name, string description, string imageName)
{
// Initialize
this.Name = name;
this.Description = description;
this.ImageName = imageName;
}
#endregion
}
}
Diese Klasse stellt die Eigenschaften bereit, um die Informationen über eine bestimmte Attraktion zu speichern.
Klicken Sie als Nächstes erneut mit der rechten Maustaste auf den Projektnamen im Projektmappenblock, und wählen Sie "Neue Datei hinzufügen>..." aus. Geben Sie CityInformation
den Namen ein, und klicken Sie auf die Schaltfläche "Neu":
Bearbeiten Sie die CityInformation.cs
Datei, und stellen Sie sicher, dass sie wie folgt aussieht:
using System;
using System.Collections.Generic;
using Foundation;
namespace tvTable
{
public class CityInformation : NSObject
{
#region Computed Properties
public string Name { get; set; }
public List<AttractionInformation> Attractions { get; set;}
public bool FlightBooked { get; set;}
#endregion
#region Constructors
public CityInformation (string name)
{
// Initialize
this.Name = name;
this.Attractions = new List<AttractionInformation> ();
}
#endregion
#region Public Methods
public void AddAttraction (AttractionInformation attraction)
{
// Mark as belonging to this city
attraction.City = this;
// Add to collection
Attractions.Add (attraction);
}
public void AddAttraction (string name, string description, string imageName)
{
// Create attraction
var attraction = new AttractionInformation (name, description, imageName);
// Mark as belonging to this city
attraction.City = this;
// Add to collection
Attractions.Add (attraction);
}
#endregion
}
}
Diese Klasse enthält alle Informationen über eine Zielstadt, eine Sammlung von Attraktionen für diese Stadt und bietet zwei Hilfsmethoden (AddAttraction
), um die Sehenswürdigkeiten der Stadt leichter hinzuzufügen.
Datenquelle der Tabellenansicht
Jede Tabellenansicht erfordert eine Datenquelle (UITableViewDataSource
), um die Daten für die Tabelle bereitzustellen und die erforderlichen Zeilen nach Bedarf in der Tabellenansicht zu generieren.
Klicken Sie im obigen Beispiel mit der rechten Maustaste auf den Projektnamen in der Projektmappen-Explorer, wählen Sie "Neue Datei hinzufügen>" aus, und rufen Sie es AttractionTableDatasource
auf, und klicken Sie auf die Schaltfläche "Neu", um sie zu erstellen. Bearbeiten Sie als Nächstes die AttractionTableDatasource.cs
Datei, und stellen Sie sicher, dass sie wie folgt aussieht:
using System;
using System.Collections.Generic;
using UIKit;
namespace tvTable
{
public class AttractionTableDatasource : UITableViewDataSource
{
#region Constants
const string CellID = "AttrCell";
#endregion
#region Computed Properties
public AttractionTableViewController Controller { get; set;}
public List<CityInformation> Cities { get; set;}
#endregion
#region Constructors
public AttractionTableDatasource (AttractionTableViewController controller)
{
// Initialize
this.Controller = controller;
this.Cities = new List<CityInformation> ();
PopulateCities ();
}
#endregion
#region Public Methods
public void PopulateCities ()
{
// Clear existing
Cities.Clear ();
// Define cities and attractions
var Paris = new CityInformation ("Paris");
Paris.AddAttraction ("Eiffel Tower", "Is a wrought iron lattice tower on the Champ de Mars in Paris, France.", "EiffelTower");
Paris.AddAttraction ("Musée du Louvre", "is one of the world's largest museums and a historic monument in Paris, France.", "Louvre");
Paris.AddAttraction ("Moulin Rouge", "French for 'Red Mill', is a cabaret in Paris, France.", "MoulinRouge");
Paris.AddAttraction ("La Seine", "Is a 777-kilometre long river and an important commercial waterway within the Paris Basin.", "RiverSeine");
Cities.Add (Paris);
var SanFran = new CityInformation ("San Francisco");
SanFran.AddAttraction ("Alcatraz Island", "Is located in the San Francisco Bay, 1.25 miles (2.01 km) offshore from San Francisco.", "Alcatraz");
SanFran.AddAttraction ("Golden Gate Bridge", "Is a suspension bridge spanning the Golden Gate strait between San Francisco Bay and the Pacific Ocean", "GoldenGateBridge");
SanFran.AddAttraction ("San Francisco", "Is the cultural, commercial, and financial center of Northern California.", "SanFrancisco");
SanFran.AddAttraction ("Telegraph Hill", "Is primarily a residential area, much quieter than adjoining North Beach.", "TelegraphHill");
Cities.Add (SanFran);
var Houston = new CityInformation ("Houston");
Houston.AddAttraction ("City Hall", "It was constructed in 1938-1939, and is located in Downtown Houston.", "CityHall");
Houston.AddAttraction ("Houston", "Is the most populous city in Texas and the fourth most populous city in the US.", "Houston");
Houston.AddAttraction ("Texas Longhorn", "Is a breed of cattle known for its characteristic horns, which can extend to over 6 ft.", "LonghornCattle");
Houston.AddAttraction ("Saturn V Rocket", "was an American human-rated expendable rocket used by NASA between 1966 and 1973.", "Rocket");
Cities.Add (Houston);
}
#endregion
#region Override Methods
public override UITableViewCell GetCell (UITableView tableView, Foundation.NSIndexPath indexPath)
{
// Get cell
var cell = tableView.DequeueReusableCell (CellID) as AttractionTableCell;
// Populate cell
cell.Attraction = Cities [indexPath.Section].Attractions [indexPath.Row];
// Return new cell
return cell;
}
public override nint NumberOfSections (UITableView tableView)
{
// Return number of cities
return Cities.Count;
}
public override nint RowsInSection (UITableView tableView, nint section)
{
// Return the number of attractions in the given city
return Cities [(int)section].Attractions.Count;
}
public override string TitleForHeader (UITableView tableView, nint section)
{
// Get the name of the current city
return Cities [(int)section].Name;
}
#endregion
}
}
Sehen wir uns einige Abschnitte des Kurses im Detail an.
Zunächst haben wir eine Konstante definiert, die den eindeutigen Bezeichner der Prototypzelle enthält (dies ist der gleiche Bezeichner, der im obigen Schnittstellen-Designer zugewiesen ist), eine Verknüpfung zurück zum Tabellenansichtscontroller hinzugefügt und Speicher für unsere Daten erstellt:
const string CellID = "AttrCell";
public AttractionTableViewController Controller { get; set;}
public List<CityInformation> Cities { get; set;}
Als Nächstes speichern wir den Tabellenansichtscontroller, erstellen und füllen unsere Datenquelle (unter Verwendung der oben definierten Datenmodelle) beim Erstellen der Klasse aus:
public AttractionTableDatasource (AttractionTableViewController controller)
{
// Initialize
this.Controller = controller;
this.Cities = new List<CityInformation> ();
PopulateCities ();
}
Aus Gründen des Beispiels erstellt die PopulateCities
Methode einfach Datenmodellobjekte im Arbeitsspeicher, aber diese können leicht aus einer Datenbank oder einem Webdienst in einer echten App gelesen werden:
public void PopulateCities ()
{
// Clear existing
Cities.Clear ();
// Define cities and attractions
var Paris = new CityInformation ("Paris");
Paris.AddAttraction ("Eiffel Tower", "Is a wrought iron lattice tower on the Champ de Mars in Paris, France.", "EiffelTower");
...
}
Die NumberOfSections
Methode gibt die Anzahl der Abschnitte in der Tabelle zurück:
public override nint NumberOfSections (UITableView tableView)
{
// Return number of cities
return Cities.Count;
}
Geben Sie für tabellenformatierte Tabellenansichten immer 1 zurück.
Die RowsInSection
Methode gibt die Anzahl der Zeilen im aktuellen Abschnitt zurück:
public override nint RowsInSection (UITableView tableView, nint section)
{
// Return the number of attractions in the given city
return Cities [(int)section].Attractions.Count;
}
Geben Sie bei "Nur-Tabellenansichten " erneut die Gesamtanzahl der Elemente in der Datenquelle zurück.
Die TitleForHeader
Methode gibt den Titel für den angegebenen Abschnitt zurück:
public override string TitleForHeader (UITableView tableView, nint section)
{
// Get the name of the current city
return Cities [(int)section].Name;
}
Lassen Sie für einen Einfachen Tabellenansichtstyp den Titel leer (""
).
Wenn Sie von der Tabellenansicht angefordert werden, erstellen und füllen Sie mit der GetCell
Methode eine Prototypzelle auf:
public override UITableViewCell GetCell (UITableView tableView, Foundation.NSIndexPath indexPath)
{
// Get cell
var cell = tableView.DequeueReusableCell (CellID) as AttractionTableCell;
// Populate cell
cell.Attraction = Cities [indexPath.Section].Attractions [indexPath.Row];
// Return new cell
return cell;
}
Weitere Informationen zum Arbeiten mit einer UITableViewDatasource
App finden Sie in der Dokumentation zu "UITableViewDatasource" von Apple.
Tabellenansichtsdelegat
Jede Tabellenansicht erfordert eine Stellvertretung (UITableViewDelegate
), um auf Benutzerinteraktionen oder andere Systemereignisse in der Tabelle zu reagieren.
Klicken Sie im obigen Beispiel mit der rechten Maustaste auf den Projektnamen in der Projektmappen-Explorer, wählen Sie "Neue Datei hinzufügen>" aus, und rufen Sie es AttractionTableDelegate
auf, und klicken Sie auf die Schaltfläche "Neu", um sie zu erstellen. Bearbeiten Sie als Nächstes die AttractionTableDelegate.cs
Datei, und stellen Sie sicher, dass sie wie folgt aussieht:
using System;
using System.Collections.Generic;
using UIKit;
namespace tvTable
{
public class AttractionTableDelegate : UITableViewDelegate
{
#region Computed Properties
public AttractionTableViewController Controller { get; set;}
#endregion
#region Constructors
public AttractionTableDelegate (AttractionTableViewController controller)
{
// Initializw
this.Controller = controller;
}
#endregion
#region Override Methods
public override void RowSelected (UITableView tableView, Foundation.NSIndexPath indexPath)
{
var attraction = Controller.Datasource.Cities [indexPath.Section].Attractions [indexPath.Row];
attraction.IsFavorite = (!attraction.IsFavorite);
// Update UI
Controller.TableView.ReloadData ();
}
public override bool CanFocusRow (UITableView tableView, Foundation.NSIndexPath indexPath)
{
// Inform caller of highlight change
RaiseAttractionHighlighted (Controller.Datasource.Cities [indexPath.Section].Attractions [indexPath.Row]);
return true;
}
#endregion
#region Events
public delegate void AttractionHighlightedDelegate (AttractionInformation attraction);
public event AttractionHighlightedDelegate AttractionHighlighted;
internal void RaiseAttractionHighlighted (AttractionInformation attraction)
{
// Inform caller
if (this.AttractionHighlighted != null) this.AttractionHighlighted (attraction);
}
#endregion
}
}
Sehen wir uns einige Abschnitte dieser Klasse in Details an.
Zunächst erstellen wir beim Erstellen der Klasse eine Verknüpfung zum Tabellenansichtscontroller:
public AttractionTableViewController Controller { get; set;}
...
public AttractionTableDelegate (AttractionTableViewController controller)
{
// Initialize
this.Controller = controller;
}
Wenn dann eine Zeile ausgewählt wird (der Benutzer klickt auf das Touch Surface der Apple Remote), möchten wir die Attraktion markieren, die durch die ausgewählte Zeile als Favorit dargestellt wird:
public override void RowSelected (UITableView tableView, Foundation.NSIndexPath indexPath)
{
var attraction = Controller.Datasource.Cities [indexPath.Section].Attractions [indexPath.Row];
attraction.IsFavorite = (!attraction.IsFavorite);
// Update UI
Controller.TableView.ReloadData ();
}
Als Nächstes möchten wir, wenn der Benutzer eine Zeile hervorgehoben (indem er ihm den Fokus mithilfe des Apple Remote Touch Surface gibt) die Details der Attraktion präsentieren, die durch diese Zeile im Abschnitt "Details" unseres Geteilten Ansichtscontrollers dargestellt wird:
public override bool CanFocusRow (UITableView tableView, Foundation.NSIndexPath indexPath)
{
// Inform caller of highlight change
RaiseAttractionHighlighted (Controller.Datasource.Cities [indexPath.Section].Attractions [indexPath.Row]);
return true;
}
...
public delegate void AttractionHighlightedDelegate (AttractionInformation attraction);
public event AttractionHighlightedDelegate AttractionHighlighted;
internal void RaiseAttractionHighlighted (AttractionInformation attraction)
{
// Inform caller
if (this.AttractionHighlighted != null) this.AttractionHighlighted (attraction);
}
Die CanFocusRow
Methode wird für jede Zeile aufgerufen, die den Fokus in der Tabellenansicht erhält. Gibt zurück true
, wenn die Zeile den Fokus erhalten kann, andernfalls wird zurückgegeben false
. Im Fall dieses Beispiels haben wir ein benutzerdefiniertes AttractionHighlighted
Ereignis erstellt, das für jede Zeile ausgelöst wird, während es den Fokus erhält.
Weitere Informationen zum Arbeiten mit einer UITableViewDelegate
App finden Sie in der Dokumentation zu "UITableViewDelegate" von Apple.
Die Zelle "Tabellenansicht"
Für jede Prototypzelle, die Sie der Tabellenansicht im Schnittstellen-Designer hinzugefügt haben, haben Sie auch eine benutzerdefinierte Instanz der Tabellenansichtszelle (UITableViewCell
) erstellt, damit Sie die neue Zelle (Zeile) auffüllen können, wie sie erstellt wird.
Doppelklicken Sie für die Beispiel-App auf die AttractionTableCell.cs
Datei, um sie zur Bearbeitung zu öffnen, und sehen Sie wie folgt aus:
using System;
using Foundation;
using UIKit;
namespace tvTable
{
public partial class AttractionTableCell : UITableViewCell
{
#region Private Variables
private AttractionInformation _attraction = null;
#endregion
#region Computed Properties
public AttractionInformation Attraction {
get { return _attraction; }
set {
_attraction = value;
UpdateUI ();
}
}
#endregion
#region Constructors
public AttractionTableCell (IntPtr handle) : base (handle)
{
}
#endregion
#region Private Methods
private void UpdateUI ()
{
// Trap all errors
try {
Title.Text = Attraction.Name;
Favorite.Hidden = (!Attraction.IsFavorite);
} catch {
// Since the UI might not be fully loaded, ignore
// all errors at this point
}
}
#endregion
}
}
Diese Klasse bietet Speicher für das Attraction Data Model -Objekt (AttractionInformation
wie oben definiert), das in der angegebenen Zeile angezeigt wird:
private AttractionInformation _attraction = null;
...
public AttractionInformation Attraction {
get { return _attraction; }
set {
_attraction = value;
UpdateUI ();
}
}
Die UpdateUI
Methode füllt die UI-Widgets (die dem Prototyp der Zelle im Schnittstellen-Designer hinzugefügt wurden) nach Bedarf auf:
private void UpdateUI ()
{
// Trap all errors
try {
Title.Text = Attraction.Name;
Favorite.Hidden = (!Attraction.IsFavorite);
} catch {
// Since the UI might not be fully loaded, ignore
// all errors at this point
}
}
Weitere Informationen zum Arbeiten mit einer UITableViewCell
App finden Sie in der UiTableViewCell-Dokumentation von Apple.
Der Tabellenansichtscontroller
Ein Tabellenansichtscontroller (UITableViewController
) verwaltet eine Tabellenansicht, die einem Storyboard über den Schnittstellen-Designer hinzugefügt wurde.
Doppelklicken Sie für die Beispiel-App auf die AttractionTableViewController.cs
Datei, um sie zur Bearbeitung zu öffnen, und sehen Sie wie folgt aus:
using System;
using Foundation;
using UIKit;
namespace tvTable
{
public partial class AttractionTableViewController : UITableViewController
{
#region Computed Properties
public AttractionTableDatasource Datasource {
get { return TableView.DataSource as AttractionTableDatasource; }
}
public AttractionTableDelegate TableDelegate {
get { return TableView.Delegate as AttractionTableDelegate; }
}
#endregion
#region Constructors
public AttractionTableViewController (IntPtr handle) : base (handle)
{
}
#endregion
#region Override Methods
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Setup table
TableView.DataSource = new AttractionTableDatasource (this);
TableView.Delegate = new AttractionTableDelegate (this);
TableView.ReloadData ();
}
#endregion
}
}
Werfen wir einen genaueren Blick auf diesen Kurs. Zunächst haben wir Verknüpfungen erstellt, um den Zugriff auf die Tabellenansicht und TableDelegate
die Tabellenansicht DataSource
zu erleichtern. Diese werden später verwendet, um zwischen der Tabellenansicht auf der linken Seite der geteilten Ansicht und der Detailansicht auf der rechten Seite zu kommunizieren.
Wenn die Tabellenansicht in den Arbeitsspeicher geladen wird, erstellen wir Instanzen von AttractionTableDatasource
und AttractionTableDelegate
(beide oben erstellt) und fügen sie an die Tabellenansicht an.
Weitere Informationen zum Arbeiten mit einer UITableViewController
App finden Sie in der Dokumentation zu Apple UITableViewController .
Alles zusammenziehen
Wie am Anfang dieses Dokuments angegeben, werden Tabellenansichten in der Regel auf einer Seite einer geteilten Ansicht als Navigation angezeigt, wobei die Details des ausgewählten Elements auf der gegenüberliegenden Seite angezeigt werden. Zum Beispiel:
Da dies ein Standardmuster in tvOS ist, sehen wir uns die letzten Schritte an, um alles zusammenzubringen und die linken und rechten Seiten der geteilten Ansicht miteinander zu interagieren.
Die Detailansicht
For the example of the travel app presented above, a custom class (AttractionViewController
) is defined for the standard View Controller presented in the right side of the Split View as the Detail View:
using System;
using Foundation;
using UIKit;
namespace tvTable
{
public partial class AttractionViewController : UIViewController
{
#region Private Variables
private AttractionInformation _attraction = null;
#endregion
#region Computed Properties
public AttractionInformation Attraction {
get { return _attraction; }
set {
_attraction = value;
UpdateUI ();
}
}
public MasterSplitView SplitView { get; set;}
#endregion
#region Constructors
public AttractionViewController (IntPtr handle) : base (handle)
{
}
#endregion
#region Public Methods
public void UpdateUI ()
{
// Trap all errors
try {
City.Text = Attraction.City.Name;
Title.Text = Attraction.Name;
SubTitle.Text = Attraction.Description;
IsFlighBooked.Hidden = (!Attraction.City.FlightBooked);
IsFavorite.Hidden = (!Attraction.IsFavorite);
IsDirections.Hidden = (!Attraction.AddDirections);
BackgroundImage.Image = UIImage.FromBundle (Attraction.ImageName);
AttractionImage.Image = BackgroundImage.Image;
} catch {
// Since the UI might not be fully loaded, ignore
// all errors at this point
}
}
#endregion
#region Override Methods
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
// Ensure the UI Updates
UpdateUI ();
}
#endregion
#region Actions
partial void BookFlight (NSObject sender)
{
// Ask user to book flight
AlertViewController.PresentOKCancelAlert ("Book Flight",
string.Format ("Would you like to book a flight to {0}?", Attraction.City.Name),
this,
(ok) => {
Attraction.City.FlightBooked = ok;
IsFlighBooked.Hidden = (!Attraction.City.FlightBooked);
});
}
partial void GetDirections (NSObject sender)
{
// Ask user to add directions
AlertViewController.PresentOKCancelAlert ("Add Directions",
string.Format ("Would you like to add directions to {0} to you itinerary?", Attraction.Name),
this,
(ok) => {
Attraction.AddDirections = ok;
IsDirections.Hidden = (!Attraction.AddDirections);
});
}
partial void MarkFavorite (NSObject sender)
{
// Flip favorite state
Attraction.IsFavorite = (!Attraction.IsFavorite);
IsFavorite.Hidden = (!Attraction.IsFavorite);
// Reload table
SplitView.Master.TableController.TableView.ReloadData ();
}
#endregion
}
}
Hier haben wir die Attraktion (AttractionInformation
) bereitgestellt, die als Eigenschaft angezeigt wird und eine UpdateUI
Methode erstellt, die die UI-Widgets auffüllt, die der Ansicht im Schnittstellen-Designer hinzugefügt wurden.
Wir haben auch eine Verknüpfung zum ControllerSplitView
für geteilte Ansicht () definiert, mit der wir Änderungen zurück zur Tabellenansicht (AcctractionTableView
) kommunizieren.
Schließlich wurden benutzerdefinierte Aktionen (Ereignisse) zu den drei UIButton
Instanzen hinzugefügt, die im Interface Designer erstellt wurden, die es dem Benutzer ermöglichen, eine Attraktion als Favorit zu markieren, Wegbeschreibungen zu einer Attraktion zu erhalten und einen Flug in eine bestimmte Stadt zu buchen.
Der Navigationsansichtscontroller
Da der Tabellenansichtscontroller in einem Navigationsansichtscontroller auf der linken Seite der geteilten Ansicht geschachtelt ist, wurde dem Navigationsansichtscontroller eine benutzerdefinierte Klasse (MasterNavigationController
) im Schnittstellen-Designer zugewiesen und wie folgt definiert:
using System;
using Foundation;
using UIKit;
namespace tvTable
{
public partial class MasterNavigationController : UINavigationController
{
#region Computed Properties
public MasterSplitView SplitView { get; set;}
public AttractionTableViewController TableController {
get { return TopViewController as AttractionTableViewController; }
}
#endregion
#region Constructors
public MasterNavigationController (IntPtr handle) : base (handle)
{
}
#endregion
}
}
Auch hier definiert diese Klasse nur einige Tastenkombinationen, um die Kommunikation über die beiden Seiten des Geteilten Ansichtscontrollers zu vereinfachen:
SplitView
- Ist ein Link zum Controller für geteilte Ansicht (MainSpiltViewController
), zu dem der Navigationsansichtscontroller gehört.TableController
– Ruft den Tabellenansichtscontroller (AttractionTableViewController
) ab, der als oberste Ansicht im Navigationsansichtscontroller angezeigt wird.
Der Controller für geteilte Ansicht
Da der Split View Controller die Basis unserer Anwendung ist, haben wir im Schnittstellen-Designer eine benutzerdefinierte Klasse (MasterSplitViewController
) erstellt und wie folgt definiert:
using System;
using Foundation;
using UIKit;
namespace tvTable
{
public partial class MasterSplitView : UISplitViewController
{
#region Computed Properties
public AttractionViewController Details {
get { return ViewControllers [1] as AttractionViewController; }
}
public MasterNavigationController Master {
get { return ViewControllers [0] as MasterNavigationController; }
}
#endregion
#region Constructors
public MasterSplitView (IntPtr handle) : base (handle)
{
}
#endregion
#region Override Methods
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Initialize
Master.SplitView = this;
Details.SplitView = this;
// Wire-up events
Master.TableController.TableDelegate.AttractionHighlighted += (attraction) => {
// Display new attraction
Details.Attraction = attraction;
};
}
#endregion
}
}
Zunächst erstellen wir Verknüpfungen zur Detailseite der geteilten Ansicht (AttractionViewController
) und zur Masterseite (MasterNavigationController
). Auch hier ist es einfacher, später zwischen den beiden Seiten zu kommunizieren.
Wenn die geteilte Ansicht in den Speicher geladen wird, fügen wir den Geteilten Ansichtscontroller an beide Seiten der geteilten Ansicht an und reagieren auf den Benutzer, der eine Attraktion in der Tabellenansicht (AttractionHighlighted
) hervorhebt, indem die neue Attraktion auf der Seite "Details " der geteilten Ansicht angezeigt wird.
Tabellenansichten im Detail
Da tvOS auf iOS basiert, sind Tabellenansichten und Tabellenansichtscontroller auf ähnliche Weise konzipiert und verhalten. Ausführlichere Informationen zum Arbeiten mit der Tabellenansicht in einer Xamarin-App finden Sie in der Dokumentation zum Arbeiten mit Tabellen und Zellen unter iOS.
Zusammenfassung
Dieser Artikel befasst sich mit dem Entwerfen und Arbeiten mit Tabellenansichten innerhalb einer Xamarin.tvOS-App. Außerdem wurde ein Beispiel für die Arbeit mit einer Tabellenansicht in einer geteilten Ansicht vorgestellt, bei der es sich um die typische Verwendung einer Tabellenansicht in einer tvOS-App handelt.