Uso delle viste tabella tvOS in Xamarin

Questo articolo illustra la progettazione e l'uso di viste tabella e controller di visualizzazione tabella all'interno di un'app Xamarin.tvOS.

In tvOS, una vista tabella viene presentata come una singola colonna di righe di scorrimento che facoltativamente possono essere organizzate in gruppi o sezioni. Le viste tabella devono essere usate quando è necessario visualizzare una grande quantità di dati in modo efficiente per l'utente, in modo chiaro da comprendere.

Le visualizzazioni tabella vengono in genere visualizzate in un lato di una visualizzazione divisa come struttura di spostamento, con i dettagli dell'elemento selezionato visualizzato sul lato opposto:

Vista tabella di esempio

Informazioni sulle viste tabella

Un UITableView oggetto visualizza una singola colonna di righe scorrevoli come elenco gerarchico di informazioni che possono essere organizzate facoltativamente in gruppi o sezioni:

Elemento selezionato

Apple offre i suggerimenti seguenti per l'uso delle tabelle:

  • Tenere presente la larghezza : provare a trovare il giusto equilibrio nelle larghezze della tabella. Se la tabella è troppo ampia, può essere difficile eseguire l'analisi da una distanza e può allontanarsi dall'area del contenuto disponibile. Se la tabella è troppo stretta, può causare il troncamento o il wrapping delle informazioni, anche in questo caso può risultare difficile per l'utente leggere dall'altra parte della stanza.
  • Mostra rapidamente sommario: per elenchi di dati di grandi dimensioni, caricare il contenuto e iniziare a visualizzare le informazioni non appena la tabella viene presentata all'utente. Se il caricamento della tabella richiede molto tempo, l'utente potrebbe perdere interesse nell'app o pensare che sia bloccato.
  • Informare l'utente di caricamenti di contenuto lunghi: se è inevitabile un tempo di caricamento lungo della tabella, presentare un indicatore indicatore di stato o attività in modo che sappiano che l'app non è bloccata.

Tipi di cella di visualizzazione tabella

Un UITableViewCell oggetto viene utilizzato per rappresentare le singole righe di dati nella vista tabella. Apple ha definito diversi tipi di cella di tabella predefiniti:

  • Impostazione predefinita : questo tipo presenta un'opzione Image sul lato sinistro della cella e titolo allineato a sinistra a destra.
  • Sottotitolo : questo tipo presenta un titolo allineato a sinistra sulla prima riga e un sottotitolo più piccolo allineato a sinistra nella riga successiva.
  • Valore 1 : questo tipo presenta un titolo allineato a sinistra con un sottotitolo più chiaro e allineato a destra sulla stessa riga.
  • Valore 2 : questo tipo presenta un titolo allineato a destra con un sottotitolo più chiaro e allineato a sinistra sulla stessa riga.

Tutti i tipi di cella di visualizzazione tabella predefiniti supportano anche elementi grafici, ad esempio indicatori di divulgazione o segni di spunta.

Inoltre, è possibile definire un tipo di cella di visualizzazione tabella personalizzata e presentare una cella prototype, creata in Progettazione interfaccia o tramite codice.

Apple offre i suggerimenti seguenti per l'uso delle celle di visualizzazione tabella:

  • Evita ritagli di testo: mantieni le singole righe di testo brevi in modo che non vengano troncate. Le parole o le frasi troncate sono difficili da analizzare dall'altra parte della stanza.
  • Prendere in considerazione lo stato della riga con stato attivo: poiché una riga diventa più grande, con angoli più arrotondati quando è attiva, è necessario testare l'aspetto della cella in tutti gli stati. Le immagini o il testo possono essere ritagliati o non corretti nello stato attivo.
  • Usare tabelle modificabili con moderazione : lo spostamento o l'eliminazione di righe di tabella richiede più tempo in tvOS rispetto a iOS. È necessario decidere attentamente se questa funzionalità aggiunge o distrae dall'app tvOS.
  • Creare tipi di cella personalizzati dove appropriato : sebbene i tipi di cella di visualizzazione tabella predefiniti siano ideali per molte situazioni, è consigliabile creare tipi di cella personalizzati per informazioni non standard per fornire maggiore controllo e presentare meglio le informazioni all'utente.

Utilizzo delle viste tabella

Il modo più semplice per usare le visualizzazioni tabella in un'app Xamarin.tvOS consiste nel creare e modificarne l'aspetto in Interface Designer.

Per iniziare, eseguire le operazioni seguenti:

  1. In Visual Studio per Mac avviare un nuovo progetto di app tvOS e selezionare app single view tvOS>>e fare clic sul pulsante Avanti:

    Selezionare App visualizzazione singola

  2. Immettere un nome per l'app e fare clic su Avanti:

    Immettere un nome per l'app

  3. Modificare il nome del progetto e il nome della soluzione oppure accettare le impostazioni predefinite e fare clic sul pulsante Crea per creare la nuova soluzione:

    Nome progetto e nome della soluzione

  4. Nel riquadro della soluzione fare doppio clic sul Main.storyboard file per aprirlo in iOS Designer:

    File Main.storyboard

  5. Selezionare ed eliminare il controller di visualizzazione predefinito:

    Selezionare ed eliminare il controller di visualizzazione predefinito

  6. Selezionare un controller di visualizzazione divisa dalla casella degli strumenti e trascinarlo nell'area di progettazione.

  7. Per impostazione predefinita, si otterrà una visualizzazione divisa con un controller visualizzazione di spostamento e un controller visualizzazione tabella sul lato sinistro e un controller di visualizzazione sul lato destro. Questo è l'utilizzo suggerito da Apple di una visualizzazione tabella in tvOS:

    Aggiungere una visualizzazione divisa

  8. Sarà necessario selezionare ogni parte della visualizzazione tabella e assegnarla un nome di classe personalizzato nella scheda Widget di Esplora proprietà in modo che sia possibile accedervi più avanti nel codice C#. Ad esempio, il controller visualizzazione tabella:

    Assegnare un nome di classe

  9. Assicurarsi di creare una classe personalizzata per il controller vista tabella, la vista tabella e le celle prototipo. Visual Studio per Mac aggiungerà le classi personalizzate all'albero del progetto durante la creazione:

    Classi personalizzate nell'albero del progetto

  10. Selezionare quindi la visualizzazione tabella nell'area di progettazione e regolarla in base alle esigenze. Ad esempio il numero di celle prototipo e lo stile (normale o raggruppato):

    Scheda widget

  11. Per ogni cella prototipo, selezionarla e assegnare un identificatore univoco nella scheda Widget di Esplora proprietà. Questo passaggio è molto importante perché sarà necessario questo identificatore in un secondo momento quando si popola la tabella. Ad esempio:AttrCell

    Scheda Widget

  12. È anche possibile selezionare questa opzione per presentare la cella come uno dei tipi di cella visualizzazione tabella predefinita tramite l'elenco a discesa Stile o impostarla su Personalizzata e usare l'area di progettazione per layout della cella trascinando in altri widget dell'interfaccia utente dalla casella degli strumenti:

    Layout delle celle

  13. Assegnare un nome univoco a ogni elemento dell'interfaccia utente nella progettazione della cella prototipo nella scheda Widget di Esplora proprietà in modo da accedervi più avanti nel codice C#:

    Assegnare un nome

  14. Ripetere il passaggio precedente per tutte le celle prototipo nella visualizzazione tabella.

  15. Assegnare quindi classi personalizzate al resto della progettazione dell'interfaccia utente, creare il layout della visualizzazione Dettagli e assegnare nomi univoci a ogni elemento dell'interfaccia utente nella visualizzazione Dettagli in modo che sia possibile accedervi anche in C#. Ad esempio:

    Layout dell'interfaccia utente

  16. Salvare le modifiche apportate allo storyboard.

Progettazione di un modello di dati

Per semplificare l'utilizzo delle informazioni visualizzate dalla visualizzazione tabella e semplificare la presentazione di informazioni dettagliate (come l'utente seleziona o evidenzia righe nella visualizzazione tabella), creare una classe o classi personalizzate da usare come modello di dati per le informazioni presentate.

Si prenda l'esempio di un'app di prenotazione viaggi che contiene un elenco di città, ognuna contenente un elenco univoco di Attrazioni che l'utente può selezionare. L'utente sarà in grado di contrassegnare un'attrazione come Preferito, selezionare per ottenere Indicazioni per un'attrazione e Prenotare un volo per una determinata città.

Per creare il modello di dati per un'attrazione, fare clic con il pulsante destro del mouse sul nome del progetto nel riquadro della soluzione e scegliere Aggiungi>nuovo file.... Immettere AttractionInformation per Nome e fare clic sul pulsante Nuovo:

Immettere AttractionInformation come Nome

Modificare il AttractionInformation.cs file e renderlo simile al seguente:

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
    }
}

Questa classe fornisce le proprietà per archiviare le informazioni su una determinata attrazione.

Fare quindi clic con il pulsante destro del mouse sul nome del progetto nel riquadro della soluzione e scegliere Aggiungi>nuovo file. Immettere CityInformation per Nome e fare clic sul pulsante Nuovo:

Immettere CityInformation come Nome

Modificare il CityInformation.cs file e renderlo simile al seguente:

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
    }
}

Questa classe contiene tutte le informazioni su una città di destinazione, una raccolta di attrazioni per tale città e fornisce due metodi helper (AddAttraction) per semplificare l'aggiunta di attrazioni alla città.

Origine dati vista tabella

Ogni vista tabella richiede un'origine dati (UITableViewDataSource) per fornire i dati per la tabella e generare le righe necessarie in base alle esigenze della vista tabella.

Per l'esempio precedente, fare clic con il pulsante destro del mouse sul nome del progetto nella Esplora soluzioni, selezionare Aggiungi>nuovo file e chiamarlo AttractionTableDatasource e fare clic sul pulsante Nuovo per creare. Modificare quindi il AttractionTableDatasource.cs file e renderlo simile al seguente:

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
    }
}

Di seguito sono riportate alcune sezioni della classe in dettaglio.

Prima di tutto, è stata definita una costante per contenere l'identificatore univoco della cella prototype (si tratta dello stesso identificatore assegnato nella finestra di progettazione dell'interfaccia precedente), è stato aggiunto un collegamento al controller di visualizzazione tabella e l'archiviazione creata per i dati:

const string CellID = "AttrCell";
public AttractionTableViewController Controller { get; set;}
public List<CityInformation> Cities { get; set;}

Successivamente, si salva il controller vista tabella, quindi si compila e si popola l'origine dati (usando i modelli di dati definiti in precedenza) quando viene creata la classe :

public AttractionTableDatasource (AttractionTableViewController controller)
{
    // Initialize
    this.Controller = controller;
    this.Cities = new List<CityInformation> ();
    PopulateCities ();
}

Ad esempio, il PopulateCities metodo crea semplicemente oggetti Modello di dati in memoria, tuttavia questi oggetti possono essere letti facilmente da un database o da un servizio Web in un'app reale:

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");
    ...
}

Il NumberOfSections metodo restituisce il numero di sezioni nella tabella:

public override nint NumberOfSections (UITableView tableView)
{
    // Return number of cities
    return Cities.Count;
}

Per le visualizzazioni tabella in stile normale , restituire sempre 1.

Il RowsInSection metodo restituisce il numero di righe nella sezione corrente:

public override nint RowsInSection (UITableView tableView, nint section)
{
    // Return the number of attractions in the given city
    return Cities [(int)section].Attractions.Count;
}

Anche in questo caso, per le viste tabella normale , restituire il numero totale di elementi nell'origine dati.

Il TitleForHeader metodo restituisce il titolo per la sezione specificata:

public override string TitleForHeader (UITableView tableView, nint section)
{
    // Get the name of the current city
    return Cities [(int)section].Name;
}

Per un tipo visualizzazione tabella normale , lasciare vuoto il titolo ("").

Infine, quando richiesto dalla vista tabella, creare e popolare una cella Prototype usando il GetCell metodo :

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;
}

Per altre informazioni sull'uso di un UITableViewDatasourceoggetto , vedere la documentazione uiTableViewDatasource di Apple.

Delegato della vista tabella

Ogni vista tabella richiede un delegato (UITableViewDelegate) per rispondere all'interazione dell'utente o ad altri eventi di sistema nella tabella.

Per l'esempio precedente, fare clic con il pulsante destro del mouse sul nome del progetto nella Esplora soluzioni, selezionare Aggiungi>nuovo file e chiamarlo AttractionTableDelegate e fare clic sul pulsante Nuovo per creare. Modificare quindi il AttractionTableDelegate.cs file e renderlo simile al seguente:

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
    }
}

Verranno ora esaminate diverse sezioni di questa classe in dettaglio.

Prima di tutto, viene creato un collegamento al controller visualizzazione tabella quando viene creata la classe :

public AttractionTableViewController Controller { get; set;}
...

public AttractionTableDelegate (AttractionTableViewController controller)
{
    // Initialize
    this.Controller = controller;
}

Quindi, quando viene selezionata una riga (l'utente fa clic su Touch Surface of the Apple Remote) vogliamo contrassegnare l'attrazione rappresentata dalla riga selezionata come Preferito:

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 ();
}

Successivamente, quando l'utente evidenzia una riga (assegnando lo stato attivo tramite Apple Remote Touch Surface) vogliamo presentare i dettagli dell'attrazione rappresentata da tale riga nella sezione Dettagli del controller di visualizzazione divisa:

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);
}

Il CanFocusRow metodo viene chiamato per ogni riga che sta per ottenere lo stato attivo nella visualizzazione Tabella. Restituisce true se la riga può ottenere lo stato attivo; in caso contrario, restituisce false. Nel caso di questo esempio, è stato creato un evento personalizzato AttractionHighlighted che verrà generato in ogni riga durante la ricezione dello stato attivo.

Per altre informazioni sull'uso di un UITableViewDelegateoggetto , vedere la documentazione uiTableViewDelegate di Apple.

Cella della vista tabella

Per ogni cella prototype aggiunta alla visualizzazione tabella in Progettazione interfaccia, è stata creata anche un'istanza personalizzata della cella visualizzazione tabella (UITableViewCell) per consentire di popolare la nuova cella (riga) durante la creazione.

Per l'app di esempio, fare doppio clic sul AttractionTableCell.cs file per aprirlo per la modifica e renderlo simile al seguente:

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
    }
}

Questa classe fornisce spazio di archiviazione per l'oggetto Attraction Data Model (AttractionInformation come definito in precedenza) visualizzato nella riga specificata:

private AttractionInformation _attraction = null;
...

public AttractionInformation Attraction {
    get { return _attraction; }
    set {
        _attraction = value;
        UpdateUI ();
    }
}

Il UpdateUI metodo popola i widget dell'interfaccia utente (aggiunti al prototipo di Cell in Interface Designer) in base alle esigenze:

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
    }
}

Per altre informazioni sull'uso di un UITableViewCelloggetto , vedere la documentazione uiTableViewCell di Apple.

Controller visualizzazione tabella

Un controller visualizzazione tabella (UITableViewController) gestisce una vista tabella aggiunta a uno storyboard tramite Progettazione interfaccia.

Per l'app di esempio, fare doppio clic sul AttractionTableViewController.cs file per aprirlo per la modifica e renderlo simile al seguente:

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
    }
}

Esaminiamo più da vicino questa classe. In primo luogo, sono stati creati collegamenti per semplificare l'accesso DataSource alle viste tabella e TableDelegate. Questi elementi verranno usati in un secondo momento per comunicare tra la visualizzazione tabella a sinistra della visualizzazione divisa e la visualizzazione dettagli a destra.

Infine, quando la vista tabella viene caricata in memoria, vengono create istanze di AttractionTableDatasource e AttractionTableDelegate (entrambe create in precedenza) e collegatele alla vista tabella.

Per altre informazioni sull'uso di un UITableViewControlleroggetto , vedere la documentazione uiTableViewController di Apple.

Tirare tutto insieme

Come indicato all'inizio di questo documento, le visualizzazioni tabella vengono in genere visualizzate in un lato di una visualizzazione divisa come spostamento, con i dettagli dell'elemento selezionato visualizzato sul lato opposto. Ad esempio:

Esecuzione dell'app di esempio

Poiché si tratta di un modello standard in tvOS, esaminiamo i passaggi finali per riunire tutto e avere i lati sinistro e destro della visualizzazione divisa interagiscono tra loro.

Visualizzazione dettagli

Per l'esempio dell'app di viaggio presentata in precedenza, viene definita una classe personalizzata (AttractionViewController) per il controller di visualizzazione standard presentato a destra della visualizzazione divisa come visualizzazione dettagli:

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
    }
}

In questo caso, abbiamo fornito l'attrazione (AttractionInformation) visualizzata come proprietà e abbiamo creato un UpdateUI metodo che popola i widget dell'interfaccia utente aggiunti alla visualizzazione in Progettazione interfaccia.

È stato anche definito un collegamento al controller di doppia visualizzazione (SplitView) che verrà usato per comunicare le modifiche alla visualizzazione tabella (AcctractionTableView).

Infine, sono state aggiunte azioni personalizzate (eventi) alle tre UIButton istanze create in Interface Designer, che consentono all'utente di contrassegnare un'attrazione come Preferito, ottenere Indicazioni per un'attrazione e Prenotare un volo in una determinata città.

Controller visualizzazione di spostamento

Poiché il controller visualizzazione tabella è annidato in un controller di visualizzazione di spostamento a sinistra della visualizzazione divisa, al controller visualizzazione di spostamento è stata assegnata una classe personalizzata (MasterNavigationController) in Progettazione interfaccia e definita come segue:

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
    }
}

Anche in questo caso, questa classe definisce solo alcuni collegamenti per semplificare la comunicazione tra i due lati del controller split view:

  • SplitView - Collegamento al controller di visualizzazione divisa (MainSpiltViewController) a cui appartiene il controller di visualizzazione di spostamento.
  • TableController : ottiene il controller visualizzazione tabella (AttractionTableViewController) visualizzato come visualizzazione superiore nel controller di visualizzazione di spostamento.

Controller di suddivisione della visualizzazione

Poiché il controller split view è la base dell'applicazione, è stata creata una classe personalizzata (MasterSplitViewController) in Progettazione interfacce e la si è definita come segue:

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
    }
}

Prima di tutto, creiamo collegamenti al lato Dettagli della doppia visualizzazione (AttractionViewController) e al lato master (MasterNavigationController). Anche in questo caso, questo semplifica la comunicazione tra i due lati in un secondo momento.

Successivamente, quando la visualizzazione divisa viene caricata in memoria, si collega il controller di visualizzazione divisa a entrambi i lati della visualizzazione divisa e si risponde all'utente evidenziando un'attrazione nella visualizzazione tabella (AttractionHighlighted) visualizzando la nuova attrazione nel lato Dettagli della visualizzazione divisa.

Visualizzazioni tabella in dettaglio

Poiché tvOS è basato su iOS, le visualizzazioni tabella e i controller di visualizzazione tabella sono progettati e si comportano in modo simile. Per informazioni più dettagliate sull'uso della vista tabella in un'app Xamarin, vedere la documentazione relativa all'uso di tabelle e celle di iOS.

Riepilogo

Questo articolo ha illustrato la progettazione e l'uso delle viste tabella all'interno di un'app Xamarin.tvOS. E ha presentato un esempio di utilizzo di una visualizzazione tabella all'interno di una doppia visualizzazione, che è l'uso tipico di una visualizzazione tabella in un'app tvOS.