Práce se zobrazeními tabulek tvOS v Xamarinu

Tento článek popisuje návrh a práci se zobrazeními tabulek a kontrolery zobrazení tabulky v aplikaci Xamarin.tvOS.

V tvOS je zobrazení tabulky prezentováno jako jeden sloupec posouvání řádků, které lze volitelně uspořádat do skupin nebo oddílů. Zobrazení tabulek by se měla použít, když potřebujete uživateli efektivně zobrazit velké množství dat, a to jasně pochopit.

Zobrazení tabulky se obvykle zobrazují na jedné straně rozděleného zobrazení jako navigace s podrobnostmi o vybrané položce zobrazené na opačné straně:

Sample table view

O zobrazeních tabulek

A UITableView zobrazí jeden sloupec posunovatelných řádků jako hierarchický seznam informací, které lze volitelně uspořádat do skupin nebo oddílů:

A selected item

Apple nabízí následující návrhy pro práci s tabulkami:

  • Mějte na paměti šířku – zkuste přeškrtnout správnou rovnováhu v šířkách tabulky. Pokud je tabulka příliš široká, může být obtížné prohledávat vzdálenost a může se dostat z dostupné oblasti obsahu. Pokud je tabulka příliš úzká, může to způsobit zkrácení nebo zabalení informací, může být opět obtížné, aby uživatel mohl číst z celé místnosti.
  • Rychle zobrazit obsah tabulky – pro velké seznamy dat opožděně načtěte obsah a začněte zobrazovat informace hned po zobrazení tabulky uživateli. Pokud načtení tabulky trvá dlouho, může uživatel přijít o vaši aplikaci nebo si myslí, že je uzamčený.
  • Informujte uživatele o dlouhých načítání obsahu – pokud je dlouhá doba načítání tabulky nepochybná, zobrazte indikátor průběhu nebo aktivity, aby věděl, že aplikace není uzamčená.

Typy buněk zobrazení tabulky

A UITableViewCell slouží k reprezentaci jednotlivých řádků dat v zobrazení tabulky. Apple definoval několik výchozích typů buněk tabulky:

  • Výchozí – Tento typ představuje možnost Obrázek na levé straně buňky a nadpis zarovnaný doleva vpravo.
  • Podnadpis – Tento typ představuje nadpis zarovnaný doleva na prvním řádku a menší titulek zarovnaný doleva na dalším řádku.
  • Hodnota 1 – Tento typ zobrazuje nadpis zarovnaný doleva se světlejším barevným titulkem zarovnaným doprava na stejném řádku.
  • Hodnota 2 – Tento typ představuje nadpis zarovnaný doprava se světlejším barevným titulkem zarovnaným doleva na stejném řádku.

Všechny výchozí typy buněk zobrazení tabulky také podporují grafické prvky, jako jsou indikátory zpřístupnění nebo značky zaškrtnutí.

Kromě toho můžete definovat vlastní typ buňky zobrazení tabulky a prezentovat prototyp buňku, kterou vytvoříte v Návrháři rozhraní nebo prostřednictvím kódu.

Apple nabízí následující návrhy pro práci s buňkami zobrazení tabulky:

  • Vyhněte se výřezu textu – Ponechte jednotlivé řádky textu krátké, aby se nezkrátily. Zkrácená slova nebo fráze jsou pro uživatele obtížné analyzovat z celé místnosti.
  • Zvažte stav prioritního řádku – protože se řádek zvětší a při fokusu bude mít větší zaoblené rohy, musíte otestovat vzhled buňky ve všech stavech. Obrázky nebo text se můžou oříznout nebo v prioritním stavu vypadat špatně.
  • Používejte upravitelné tabulky střídmě – Přesunutí nebo odstranění řádků tabulky je v tvOS časově náročnější než v iOSu. Musíte se pečlivě rozhodnout, jestli tato funkce přidá vaši aplikaci tvOS nebo ji ruší.
  • Vytvořit vlastní typy buněk tam, kde je to vhodné – i když jsou předdefinované typy buněk zobrazení tabulky skvělé pro mnoho situací, zvažte vytvoření vlastních typů buněk pro nestandardní informace, které poskytují větší kontrolu a lepší prezentaci informací uživateli.

Práce se zobrazeními tabulek

Nejjednodušší způsob, jak pracovat se zobrazeními tabulek v aplikaci Xamarin.tvOS, je vytvořit a upravit jejich vzhled v Návrháři rozhraní.

Začněte následujícím postupem:

  1. V Visual Studio pro Mac spusťte nový projekt aplikace tvOS a vyberte aplikaci tvOS>>s jedním zobrazením a klikněte na tlačítko Další:

    Select Single View App

  2. Zadejte název aplikace a klikněte na Další:

    Enter a Name for the app

  3. Upravte název projektu a název řešení nebo přijměte výchozí hodnoty a kliknutím na tlačítko Vytvořit vytvořte nové řešení:

    The Project Name and Solution Name

  4. V oblasti řešení poklikáním Main.storyboard otevřete soubor v iOS Designeru:

    The Main.storyboard file

  5. Vyberte a odstraňte výchozí kontroler zobrazení:

    Select and delete the Default View Controller

  6. Ze sady nástrojů vyberte ovladačrozděleného zobrazení a přetáhněte ho na návrhovou plochu.

  7. Ve výchozím nastavení získáte rozdělené zobrazení s kontrolerem navigačního zobrazení a kontrolerem zobrazení tabulky na levé straně a kontrolerem zobrazení na pravé straně. Toto je navrhované použití zobrazení tabulky v tvOS společnosti Apple:

    Add a Split View

  8. Budete muset vybrat všechny části zobrazení tabulky a přiřadit mu vlastní název třídy na kartě Widget v Průzkumníkuvlastností, abyste k nim měli přístup později v kódu jazyka C#. Například kontroler zobrazení tabulky:

    Assign a class name

  9. Ujistěte se, že vytvoříte vlastní třídu pro kontroleru zobrazení tabulky, zobrazení tabulky a všechny prototypové buňky. Visual Studio pro Mac přidá vlastní třídy do stromu projektu při jejich vytváření:

    The custom classes in the Project Tree

  10. Dále vyberte zobrazení tabulky na návrhové ploše a podle potřeby upravte její vlastnosti. Například počet prototypových buněk a styl (prostý nebo seskupený):

    The widget tab

  11. Pro každou buňku prototypu ji vyberte a na kartě Widget v Průzkumníku vlastností přiřaďte jedinečný identifikátor. Tento krok je velmi důležitý , protože tento identifikátor budete potřebovat později při naplnění tabulky. Příklad AttrCell:

    The Widget Tab

  12. Buňku můžete také zobrazit jako jeden z výchozích typů buněk zobrazení tabulky pomocí rozevíracího seznamu Styl nebo ji nastavit na Vlastní a pomocí návrhové plochy můžete buňku rozložení buňky přetažením do jiných widgetů uživatelského rozhraní z panelu nástrojů:

    The cell layout

  13. Přiřaďte každému prvku uživatelského rozhraní v návrhu prototypu buňky na kartě Widget v Průzkumníkuvlastností jedinečný název, abyste k nim měli přístup později v kódu jazyka C#:

    Assign a name

  14. Opakujte výše uvedený krok pro všechny prototypové buňky v zobrazení tabulky.

  15. Dále přiřaďte vlastní třídy ke zbytku návrhu uživatelského rozhraní, rozložení zobrazení Podrobností a přiřazení jedinečných názvů ke každému prvku uživatelského rozhraní v zobrazení Podrobnosti, abyste k nim měli přístup i v jazyce C#. Příklad:

    The UI layout

  16. Uložte změny do scénáře.

Návrh datového modelu

Chcete-li usnadnit práci s informacemi, které bude zobrazení tabulky zobrazovat, a usnadnit prezentaci podrobných informací (když uživatel vybere nebo zvýrazní řádky v zobrazení tabulky), vytvořte vlastní třídu nebo třídy, které budou fungovat jako datový model pro prezentované informace.

Podívejte se na příklad aplikace pro cestovní rezervace, která obsahuje seznam měst, z nichž každý obsahuje jedinečný seznam atrakcí , které uživatel může vybrat. Uživatel bude moct označit atrakce jako oblíbenou položku, vybrat si navigační pokyny k atrakcí a rezervovat let do daného města.

Chcete-li vytvořit datový model pro atrakcí, klikněte pravým tlačítkem myši na název projektu v oblasti řešení a vyberte Přidat>nový soubor.... Zadejte AttractionInformation název a klikněte na tlačítko Nový:

Enter AttractionInformation for the Name

AttractionInformation.cs Upravte soubor a udělejte ho takto:

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

Tato třída poskytuje vlastnosti pro uložení informací o dané atrakce.

Potom znovu klikněte pravým tlačítkem na název projektu v oblasti řešení a vyberte Přidat>nový soubor.... Zadejte CityInformation název a klikněte na tlačítko Nový:

Enter CityInformation for the Name

CityInformation.cs Upravte soubor a udělejte ho takto:

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

Tato třída obsahuje všechny informace o cílovém městě, kolekci atrakcí pro toto město a poskytuje dvě pomocné metody (AddAttraction), které usnadňují přidávání atrakcí do města.

Zdroj dat zobrazení tabulky

Každé zobrazení tabulky vyžaduje zdroj dat (UITableViewDataSource) k zadání dat pro tabulku a vygenerování potřebných řádků podle potřeby zobrazení tabulky.

V příkladu uvedeném výše klikněte pravým tlačítkem myši na název projektu v Průzkumník řešení, vyberte Přidat>nový soubor... a zavolejte ho AttractionTableDatasource a kliknutím na tlačítko Nový vytvořte. Potom upravte AttractionTableDatasource.cs soubor a udělejte ho takto:

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

Pojďme se podrobněji podívat na několik částí třídy.

Nejprve jsme definovali konstantu pro uložení jedinečného identifikátoru prototypové buňky (to je stejný identifikátor přiřazený v návrháři rozhraní výše), přidali zástupce zpět do kontroleru zobrazení tabulky a vytvořili úložiště pro naše data:

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

Dále uložíme kontroler zobrazení tabulky a pak při vytváření třídy sestavíme a naplníme zdroj dat (pomocí datových modelů definovaných výše):

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

V zájmu příkladu PopulateCities metoda jednoduše vytvoří objekty datového modelu v paměti, ale můžou být snadno čitelné z databáze nebo webové služby v reálné aplikaci:

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

Metoda NumberOfSections vrátí počet oddílů v tabulce:

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

Pro zobrazení tabulky ve stylu prostého stylu vždy vrátí hodnotu 1.

Metoda RowsInSection vrátí počet řádků v aktuálním oddílu:

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

Opět platí, že pro zobrazení prostých tabulek vrátí celkový počet položek ve zdroji dat.

Metoda TitleForHeader vrátí název pro daný oddíl:

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

U typu zobrazení prosté tabulky nechejte název prázdný ("").

Nakonec, když požaduje zobrazení tabulky, vytvořte a naplňte prototyp buňku GetCell pomocí metody:

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

Další informace o práci s objektem UITableViewDatasourcea , naleznete v dokumentaci k UITableViewDatasource společnosti Apple.

Delegát zobrazení tabulky

Každé zobrazení tabulky vyžaduje, aby delegát (UITableViewDelegate) reagoval na interakci uživatele nebo na jiné systémové události v tabulce.

V příkladu uvedeném výše klikněte pravým tlačítkem myši na název projektu v Průzkumník řešení, vyberte Přidat>nový soubor... a zavolejte ho AttractionTableDelegate a kliknutím na tlačítko Nový vytvořte. Potom upravte AttractionTableDelegate.cs soubor a udělejte ho takto:

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

Pojďme se podívat na několik částí této třídy v podrobnostech.

Nejprve vytvoříme zástupce kontroleru zobrazení tabulky při vytvoření třídy:

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

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

Když je pak vybrán řádek (uživatel klikne na dotykový povrch Apple Remote), chceme označit atrakcí reprezentovanou vybraným řádkem jako oblíbený:

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

Když uživatel zvýrazní řádek (tím, že ho zvýrazní pomocí zařízení Apple Remote Touch Surface), chceme zobrazit podrobnosti atrakce reprezentované tímto řádkem v části Podrobnosti v našem rozděleném ovladači zobrazení:

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

Metoda CanFocusRow se volá pro každý řádek, který se chystá získat fokus v zobrazení tabulky. Vrátí, true pokud řádek může získat fokus, jinak vrátit false. V případě tohoto příkladu jsme vytvořili vlastní AttractionHighlighted událost, která bude vyvolána na každém řádku při příjmu fokusu.

Další informace o práci s nástrojem UITableViewDelegate, naleznete v dokumentaci k UITableViewDelegate společnosti Apple.

Buňka zobrazení tabulky

Pro každou prototypovou buňku, kterou jste přidali do zobrazení tabulky v Návrháři rozhraní, jste také vytvořili vlastní instanci buňky zobrazení tabulky (UITableViewCell), která vám umožní naplnit novou buňku (řádek) při vytváření.

V ukázkové aplikaci poklikáním AttractionTableCell.cs otevřete soubor pro úpravy a udělejte ho takto:

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

Tato třída poskytuje úložiště pro objekt datového modelu atrakce (AttractionInformation jak je definováno výše) zobrazený v daném řádku:

private AttractionInformation _attraction = null;
...

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

Metoda UpdateUI naplní widgety uživatelského rozhraní (které byly přidány do prototypu buňky v Návrháři rozhraní) podle potřeby:

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

Další informace o práci s objektem UITableViewCell, naleznete v dokumentaci k UITableViewCell společnosti Apple.

Kontroler zobrazení tabulky

Kontroler zobrazení tabulky (UITableViewController) spravuje zobrazení tabulky, které bylo přidáno do scénáře prostřednictvím Návrháře rozhraní.

V ukázkové aplikaci poklikáním AttractionTableViewController.cs otevřete soubor pro úpravy a udělejte ho takto:

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

Pojďme se podrobněji podívat na tuto třídu. Nejprve jsme vytvořili klávesové zkratky, které usnadňují přístup k zobrazení DataSource tabulky a TableDelegate. Později použijeme ke komunikaci mezi zobrazením tabulky na levé straně rozděleného zobrazení a zobrazením podrobností vpravo.

A konečně, když se zobrazení tabulky načte do paměti, vytvoříme instance a AttractionTableDatasourceAttractionTableDelegate (oba jsme vytvořili výše) a připojíme je k zobrazení tabulky.

Další informace o práci s objektem UITableViewController, naleznete v dokumentaci k UITableViewController společnosti Apple.

Stahovat vše dohromady

Jak je uvedeno na začátku tohoto dokumentu, zobrazení tabulky se obvykle zobrazují na jedné straně rozděleného zobrazení jako navigace s podrobnostmi o vybrané položce zobrazené na opačné straně. Příklad:

Sample app run

Vzhledem k tomu, že se jedná o standardní vzor v tvOS, podívejme se na poslední kroky, abychom všechno spojili a měli levé a pravé strany rozděleného zobrazení vzájemně interagují.

Zobrazení podrobností

V příkladu výše uvedené cestovní aplikace je definována vlastní třída (AttractionViewController) pro standardní kontroler zobrazení prezentovaný na pravé straně rozděleného zobrazení jako zobrazení podrobností:

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

Zde jsme zadali objekt Attraction (AttractionInformation), který se zobrazuje jako vlastnost, a vytvořili jsme metodu UpdateUI , která naplní widgety uživatelského rozhraní přidané do zobrazení v Návrháři rozhraní.

Také jsme definovali zástupce zpět na řadič rozděleného zobrazení (SplitView), který použijeme ke komunikaci změn zpět do zobrazení tabulky (AcctractionTableView).

Nakonec byly přidány vlastní akce (události) do tří UIButton instancí vytvořených v Návrháři rozhraní, které uživateli umožňují označit atrakce jako oblíbené, získat navigační pokyny k atrakcí a rezervovat let do daného města.

Kontroler zobrazení navigace

Vzhledem k tomu, že řadič zobrazení tabulky je vnořený do kontroleru navigačního zobrazení na levé straně rozděleného zobrazení, byl řadič navigačního zobrazení přiřazen vlastní třídu (MasterNavigationController) v Návrháři rozhraní a definován takto:

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

Tato třída jednoduše definuje několik zkratek, které usnadňují komunikaci mezi dvěma stranami kontroleru rozděleného zobrazení:

  • SplitView - Je odkaz na řadič rozděleného zobrazení (MainSpiltViewController), do kterého patří kontroler navigačního zobrazení.
  • TableController - Získá řadič zobrazení tabulky (AttractionTableViewController), který je uveden jako horní zobrazení v kontroleru navigačního zobrazení.

Kontroler rozděleného zobrazení

Vzhledem k tomu, že Split View Controller je základem naší aplikace, vytvořili jsme pro ni vlastní třídu (MasterSplitViewController) v Návrháři rozhraní a definovali ji takto:

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

Nejprve vytvoříme zástupce na straně Podrobností rozděleného zobrazení (AttractionViewController) a na stranu předlohy (MasterNavigationController). Opět to usnadňuje komunikaci mezi oběma stranami později.

Když se dále načte rozdělené zobrazení do paměti, připojíme řadič rozděleného zobrazení na obě strany rozděleného zobrazení a odpovíme uživateli, který zvýrazní atrakce v zobrazení tabulky (AttractionHighlighted) zobrazením nové atrakce na straně Podrobností v rozděleném zobrazení.

Úplnou implementaci zobrazení tabulky uvnitř rozděleného zobrazení najdete v ukázkové aplikaci tvTables .

Zobrazení tabulek v podrobnostech

Vzhledem k tomu, že tvOS je založený na iOSu, jsou zobrazení tabulek a kontrolery zobrazení tabulky navrženy a chovají se podobným způsobem. Podrobnější informace o práci se zobrazením tabulky v aplikaci Xamarin najdete v naší dokumentaci k práci s tabulkami a buňkami v iOSu.

Shrnutí

Tento článek popisuje návrh a práci se zobrazeními tabulek v aplikaci Xamarin.tvOS. A představil příklad práce se zobrazením tabulky uvnitř rozděleného zobrazení, což je typické použití zobrazení tabulky v aplikaci tvOS.