Praca z widokami tabel systemu tvOS na platformie Xamarin

W tym artykule opisano projektowanie i pracę z widokami tabel i kontrolerami widoku tabel w aplikacji platformy Xamarin.tvOS.

W systemie tvOS widok tabeli jest przedstawiany jako pojedyncza kolumna przewijania wierszy, które mogą być opcjonalnie zorganizowane w grupy lub sekcje. Widoki tabel powinny być używane, gdy trzeba efektywnie wyświetlać użytkownikowi dużą ilość danych, aby zrozumieć sposób.

Widoki tabeli są zwykle wyświetlane po jednej stronie widoku podzielonego jako nawigacja ze szczegółami wybranego elementu wyświetlanego po przeciwnej stronie:

Przykładowy widok tabeli

Informacje o widokach tabeli

Obiekt UITableView wyświetla jedną kolumnę wierszy z możliwością przewijania jako hierarchiczną listę informacji, które mogą być opcjonalnie zorganizowane w grupy lub sekcje:

Wybrany element

Firma Apple ma następujące sugestie dotyczące pracy z tabelami:

  • Pamiętaj o szerokości — spróbuj wyrównyć poprawną równowagę w szerokościach tabeli. Jeśli tabela jest zbyt szeroka, skanowanie z dystansu może być trudne i może zabrać go z dostępnego obszaru zawartości. Jeśli tabela jest zbyt wąskia, może to spowodować obcięcie lub opakowywanie informacji, co może być trudne dla użytkownika do odczytania z całego pokoju.
  • Pokaż zawartość spisu szybko — w przypadku dużych list danych załaduj zawartość z opóźnieniem i zacznij wyświetlać informacje natychmiast po wyświetleniu tabeli użytkownikowi. Jeśli ładowanie tabeli trwa długo, użytkownik może utracić zainteresowanie aplikacją lub sądzić, że jest zablokowany.
  • Poinformuj użytkownika o długich obciążeniach zawartości — jeśli długi czas ładowania tabeli jest nieunikniony, wyświetl pasek postępu lub wskaźnik aktywności, aby wiedzieć, że aplikacja nie została zablokowana.

Typy komórek widoku tabeli

Element a UITableViewCell służy do reprezentowania poszczególnych wierszy danych w widoku tabeli. Firma Apple zdefiniowała kilka domyślnych typów komórek tabeli:

  • Ustawienie domyślne — ten typ przedstawia opcję Obraz po lewej stronie komórki i wyrównany do lewej strony tytuł po prawej stronie.
  • Podtytuł — ten typ przedstawia wyrównany do lewej tytuł w pierwszym wierszu i mniejszy wyrównany do lewej podtytuł w następnym wierszu.
  • Wartość 1 — ten typ przedstawia wyrównany do lewej tytuł z jaśniejszym, wyrównanym do prawej podtytułem w tym samym wierszu.
  • Wartość 2 — ten typ przedstawia wyrównany do prawej tytuł z jaśniejszym kolorem, wyrównany do lewej podtytuł w tym samym wierszu.

Wszystkie domyślne typy komórek widoku tabeli obsługują również elementy graficzne, takie jak wskaźniki ujawniania lub znaczniki wyboru.

Ponadto można zdefiniować niestandardowy typ komórki widoku tabeli i przedstawić prototypową komórkę, którą można utworzyć w Projektant interfejsu lub za pomocą kodu.

Firma Apple ma następujące sugestie dotyczące pracy z komórkami widoku tabeli:

  • Unikaj wycinania tekstu — zachowaj krótkie wiersze tekstu, aby nie zostały obcięte. Obcięte wyrazy lub frazy są trudne dla użytkownika do analizowania z całego pokoju.
  • Rozważ stan wiersza ukierunkowanego — ponieważ wiersz staje się większy, z bardziej zaokrąglonymi rogami, gdy fokus, musisz przetestować wygląd komórki we wszystkich stanach. Obrazy lub tekst mogą zostać obcięte lub wyglądać niepoprawnie w stanie Fokus.
  • Używanie tabel edytowalnych oszczędnie — przenoszenie lub usuwanie wierszy tabeli jest bardziej czasochłonne w systemie tvOS niż iOS. Należy dokładnie zdecydować, czy ta funkcja doda lub odwróci uwagę od aplikacji tvOS.
  • Tworzenie niestandardowych typów komórek tam, gdzie jest to właściwe — chociaż wbudowane typy komórek widoku tabeli są doskonałe w wielu sytuacjach, rozważ utworzenie niestandardowych typów komórek dla niestandardowych informacji, aby zapewnić większą kontrolę i lepiej przedstawić informacje użytkownikowi.

Praca z widokami tabel

Najprostszym sposobem pracy z widokami tabel w aplikacji platformy Xamarin.tvOS jest utworzenie i zmodyfikowanie ich wyglądu w Projektant interfejsu.

Aby rozpocząć pracę, wykonaj następujące czynności:

  1. W Visual Studio dla komputerów Mac uruchom nowy projekt aplikacji tvOS i wybierz pozycję aplikacja tvOS>Single View App> i kliknij przycisk Dalej:

    Wybieranie aplikacji z pojedynczym widokiem

  2. Wprowadź nazwę aplikacji i kliknij przycisk Dalej:

    Wprowadź nazwę aplikacji

  3. Dostosuj nazwę projektu i nazwę rozwiązania lub zaakceptuj wartości domyślne i kliknij przycisk Utwórz, aby utworzyć nowe rozwiązanie:

    Nazwa projektu i nazwa rozwiązania

  4. W okienku rozwiązania kliknij Main.storyboard dwukrotnie plik, aby otworzyć go w Projektant systemu iOS:

    Plik Main.storyboard

  5. Wybierz i usuń kontroler widoku domyślnego:

    Wybieranie i usuwanie domyślnego kontrolera widoku

  6. Wybierz kontroler widoku podzielonego z przybornika i przeciągnij go na powierzchnię projektową.

  7. Domyślnie uzyskasz widok podziału z kontrolerem widoku nawigacji i kontrolerem widoku tabeli po lewej stronie i kontrolerem widoku widoku w prawej stronie. Jest to sugerowane użycie widoku tabeli przez firmę Apple w systemie tvOS:

    Dodawanie widoku podzielonego

  8. Musisz wybrać każdą część widoku tabeli i przypisać jej niestandardową nazwę klasy na karcie Widżet Eksploratora właściwości, aby można było uzyskać do niego dostęp później w kodzie języka C#. Na przykład kontroler widoku tabeli:

    Przypisywanie nazwy klasy

  9. Upewnij się, że utworzono klasę niestandardową dla kontrolera widoku tabeli, widoku tabeli i wszystkich prototypowych komórek. Visual Studio dla komputerów Mac doda klasy niestandardowe do drzewa projektu podczas ich tworzenia:

    Klasy niestandardowe w drzewie projektu

  10. Następnie wybierz widok tabeli na powierzchni projektowej i dostosuj jej właściwości zgodnie z potrzebami. Na przykład liczba prototypowych komórek i styl (zwykły lub pogrupowany):

    Karta widżetu

  11. Dla każdej komórki prototypu wybierz ją i przypisz unikatowy identyfikator na karcie Widżet Eksploratora właściwości. Ten krok jest bardzo ważny , ponieważ ten identyfikator będzie potrzebny później podczas wypełniania tabeli. Na przykład:AttrCell

    Karta Widżet

  12. Możesz również wybrać, aby wyświetlić komórkę jako jeden z domyślnych typów komórek widoku tabeli za pomocą listy rozwijanej Styl lub ustawić go na niestandardowy i użyć powierzchni projektowej do układu komórki, przeciągając inne widżety interfejsu użytkownika z przybornika:

    Układ komórki

  13. Przypisz unikatową nazwę do każdego elementu interfejsu użytkownika w projekcie prototypowej komórki na karcie Widżet Eksploratora właściwości, aby uzyskać do nich dostęp w dalszej części kodu języka C#:

    Przypisywanie nazwy

  14. Powtórz powyższy krok dla wszystkich prototypowych komórek w widoku tabeli.

  15. Następnie przypisz klasy niestandardowe do pozostałej części projektu interfejsu użytkownika, układ widoku Szczegóły i przypisz unikatowe nazwy do każdego elementu interfejsu użytkownika w widoku Szczegóły, aby można było uzyskać do nich dostęp również w języku C#. Na przykład:

    Układ interfejsu użytkownika

  16. Zapisz zmiany w scenorysie.

Projektowanie modelu danych

Aby ułatwić pracę z informacjami wyświetlanymi w widoku tabeli i ułatwić prezentowanie szczegółowych informacji (gdy użytkownik wybiera lub wyróżnia wiersze w widoku tabeli), utwórz niestandardową klasę lub klasy do działania jako model danych dla prezentowanych informacji.

Zapoznaj się z przykładem aplikacji do rezerwacji podróży, która zawiera listę Miast, z których każdy zawiera unikatową listę atrakcji, które użytkownik może wybrać. Użytkownik będzie mógł oznaczyć atrakcję jako ulubioną, wybrać opcję , aby uzyskać wskazówki do atrakcji i zarezerwować lot do danego miasta.

Aby utworzyć model danych dla atrakcji, kliknij prawym przyciskiem myszy nazwę projektu w okienku rozwiązania i wybierz polecenie Dodaj>nowy plik.... Wprowadź AttractionInformation nazwę i kliknij przycisk Nowy:

Wprowadź ciąg AttractionInformation jako nazwę

Zmodyfikuj AttractionInformation.cs plik i utwórz go w następujący sposób:

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

Ta klasa udostępnia właściwości do przechowywania informacji o danej atrakcji.

Następnie ponownie kliknij prawym przyciskiem myszy nazwę projektu w okienku rozwiązania i wybierz polecenie Dodaj>nowy plik.... Wprowadź CityInformation nazwę i kliknij przycisk Nowy:

Wprowadź cityInformation jako nazwę

Zmodyfikuj CityInformation.cs plik i utwórz go w następujący sposób:

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

Ta klasa zawiera wszystkie informacje o docelowym mieście, kolekcję atrakcji dla tego miasta i udostępnia dwie metody pomocnicze (AddAttraction), aby ułatwić dodawanie atrakcji do miasta.

Źródło danych widoku tabeli

Każdy widok tabeli wymaga źródła danych (UITableViewDataSource), aby podać dane dla tabeli i wygenerować niezbędne wiersze zgodnie z wymaganiami widoku tabeli.

W przykładzie podanym powyżej kliknij prawym przyciskiem myszy nazwę projektu w Eksplorator rozwiązań, wybierz polecenie Dodaj>nowy plik... i wywołaj goAttractionTableDatasource, a następnie kliknij przycisk Nowy, aby utworzyć. Następnie zmodyfikuj AttractionTableDatasource.cs plik i utwórz go w następujący sposób:

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

Przyjrzyjmy się kilku sekcjom klasy szczegółowo.

Najpierw zdefiniowaliśmy stałą do przechowywania unikatowego identyfikatora komórki prototypu (jest to ten sam identyfikator przypisany w powyższym Projektant interfejsu), dodano skrót z powrotem do kontrolera widoku tabeli i utworzono magazyn dla naszych danych:

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

Następnie zapiszemy kontroler widoku tabeli, a następnie skompilujemy i wypełnimy nasze źródło danych (przy użyciu modeli danych zdefiniowanych powyżej) podczas tworzenia klasy:

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

Na przykład metoda po prostu tworzy obiekty modelu danych w pamięci, PopulateCities jednak można je łatwo odczytać z bazy danych lub usługi internetowej w rzeczywistej aplikacji:

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 zwraca liczbę sekcji w tabeli:

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

W przypadku widoków tabeli w zwykłych stylach zawsze zwracaj wartość 1.

Metoda RowsInSection zwraca liczbę wierszy w bieżącej sekcji:

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

Ponownie w przypadku widoków zwykłych tabel zwraca łączną liczbę elementów w źródle danych.

Metoda TitleForHeader zwraca tytuł dla danej sekcji:

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

W przypadku typu Zwykły widok tabeli pozostaw tytuł pusty ("").

Na koniec, gdy zażądasz widoku tabeli, utwórz i wypełnij prototypową komórkę przy użyciu GetCell 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;
}

Aby uzyskać więcej informacji na temat pracy z elementem UITableViewDatasource, zobacz dokumentację UITableViewDatasource firmy Apple.

Delegat widoku tabeli

Każdy widok tabeli wymaga delegata (UITableViewDelegate) w celu reagowania na interakcję użytkownika lub inne zdarzenia systemowe w tabeli.

W przykładzie podanym powyżej kliknij prawym przyciskiem myszy nazwę projektu w Eksplorator rozwiązań, wybierz polecenie Dodaj>nowy plik... i wywołaj goAttractionTableDelegate, a następnie kliknij przycisk Nowy, aby utworzyć. Następnie zmodyfikuj AttractionTableDelegate.cs plik i utwórz go w następujący sposób:

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

Przyjrzyjmy się kilku sekcjom tej klasy w szczegółach.

Najpierw utworzymy skrót do kontrolera widoku tabeli podczas tworzenia klasy:

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

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

Następnie po wybraniu wiersza (użytkownik kliknie powierzchnię dotykową urządzenia Apple Remote) chcemy oznaczyć atrakcję reprezentowaną przez wybrany wiersz jako ulubiony:

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

Następnie, gdy użytkownik wyróżni wiersz (dając mu fokus przy użyciu urządzenia Apple Remote Touch Surface), chcemy przedstawić szczegóły atrakcji reprezentowanej przez ten wiersz w sekcji Szczegóły naszego kontrolera widoku podzielonego:

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 jest wywoływana CanFocusRow dla każdego wiersza, który ma uzyskać fokus w widoku tabeli. Zwróć wartość true , jeśli wiersz może uzyskać fokus, w przeciwnym razie zwróć wartość false. W przypadku tego przykładu utworzyliśmy zdarzenie niestandardowe AttractionHighlighted , które zostanie zgłoszone w każdym wierszu, gdy otrzymuje fokus.

Aby uzyskać więcej informacji na temat pracy z elementem , zobacz dokumentację UITableViewDelegateUITableViewDelegate firmy Apple.

Komórka widoku tabeli

Dla każdej komórki prototypu dodanej do widoku tabeli w Projektant interfejsu utworzono również niestandardowe wystąpienie komórki widoku tabeli (UITableViewCell), aby umożliwić wypełnienie nowej komórki (wiersza) podczas jej tworzenia.

Na przykładowej aplikacji kliknij AttractionTableCell.cs dwukrotnie plik, aby otworzyć go do edycji i ustawić go w następujący sposób:

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

Ta klasa udostępnia magazyn dla obiektu Modelu danych atrakcji (AttractionInformation zgodnie z definicją powyżej) wyświetlaną w danym wierszu:

private AttractionInformation _attraction = null;
...

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

Metoda UpdateUI wypełnia widżety interfejsu użytkownika (które zostały dodane do prototypu komórki w Projektant interfejsu) zgodnie z wymaganiami:

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

Aby uzyskać więcej informacji na temat pracy z elementem UITableViewCell, zobacz dokumentację UITableViewCell firmy Apple.

Kontroler widoku tabeli

Kontroler widoku tabeli (UITableViewController) zarządza widokiem tabeli, który został dodany do scenorysu za pośrednictwem Projektant interfejsu.

Na przykładowej aplikacji kliknij AttractionTableViewController.cs dwukrotnie plik, aby otworzyć go do edycji i ustawić go w następujący sposób:

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

Przyjrzyjmy się bliżej tej klasie. Najpierw utworzyliśmy skróty, aby ułatwić dostęp do widoków DataSource tabel i TableDelegate. Użyjemy tych elementów później do komunikacji między widokiem tabeli po lewej stronie widoku podziału i widoku szczegółów po prawej stronie.

Na koniec, gdy widok tabeli jest ładowany do pamięci, tworzymy wystąpienia AttractionTableDatasource obiektów i AttractionTableDelegate (utworzonych powyżej) i dołączamy je do widoku tabeli.

Aby uzyskać więcej informacji na temat pracy z elementem UITableViewController, zobacz dokumentację UITableViewController firmy Apple.

Ściąganie wszystkiego razem

Jak określono na początku tego dokumentu, widoki tabeli są zwykle wyświetlane po jednej stronie widoku podziału jako nawigacji ze szczegółami wybranego elementu wyświetlanego po przeciwnej stronie. Na przykład:

Uruchamianie przykładowej aplikacji

Ponieważ jest to standardowy wzorzec w systemie tvOS, przyjrzyjmy się ostatnim krokom, aby połączyć wszystkie elementy i mieć lewe i prawe strony widoku podzielonego współdziałają ze sobą.

Widok szczegółów

W przykładzie przedstawionej powyżej aplikacji podróży klasa niestandardowa (AttractionViewController) jest zdefiniowana dla standardowego kontrolera widoku przedstawionego po prawej stronie widoku podzielonego jako widok szczegółowy:

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

W tym miejscu udostępniliśmy funkcję Atrakcja (AttractionInformation) wyświetlaną jako właściwość i utworzono metodęUpdateUI, która wypełnia widżety interfejsu użytkownika dodane do widoku w Projektant interfejsu.

Zdefiniowaliśmy również skrót z powrotem do kontrolera widoku podzielonego (SplitView), który będzie używany do przekazywania zmian z powrotem do widoku tabeli (AcctractionTableView).

Na koniec akcje niestandardowe (zdarzenia) zostały dodane do trzech UIButton wystąpień utworzonych w interfejsie Projektant, które pozwalają użytkownikowi oznaczyć atrakcję jako ulubioną, uzyskać wskazówki do atrakcji i zarezerwować lot do danego miasta.

Kontroler widoku nawigacji

Ponieważ kontroler widoku tabeli jest zagnieżdżony w kontrolerze widoku nawigacji po lewej stronie widoku podziału, kontroler widoku nawigacji został przypisany do klasy niestandardowej (MasterNavigationController) w Projektant interfejsu i zdefiniowany w następujący sposób:

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

Ponownie ta klasa definiuje kilka skrótów, aby ułatwić komunikację po obu stronach kontrolera widoku podzielonego:

  • SplitView - To link do kontrolera widoku podzielonego (MainSpiltViewController), do którego należy kontroler widoku nawigacji.
  • TableController — Pobiera kontroler widoku tabeli (AttractionTableViewController), który jest wyświetlany jako widok górny w kontrolerze widoku nawigacji.

Kontroler widoku podzielonego

Ponieważ kontroler widoku podzielonego jest podstawą naszej aplikacji, utworzyliśmy dla niej klasę niestandardową (MasterSplitViewController) w Projektant interfejsu i zdefiniowaliśmy ją w następujący sposób:

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

Najpierw tworzymy skróty do strony Szczegóły widoku podzielonego (AttractionViewController) i strony wzorca (MasterNavigationController). Ponownie ułatwia to komunikację między obiema stronami później.

Następnie, gdy widok podziału jest ładowany do pamięci, dołączamy kontroler widoku podziału do obu stron widoku podziału i odpowiadamy na użytkownika wyróżniającego atrakcję w widoku tabeli (AttractionHighlighted), wyświetlając nową atrakcję po stronie Szczegóły widoku podziału.

Widoki tabeli w szczegółach

Ponieważ system tvOS jest oparty na systemie iOS, widoki tabel i kontrolery widoku tabel są projektowane i zachowują się w podobny sposób. Aby uzyskać bardziej szczegółowe informacje na temat pracy z widokiem tabeli w aplikacji platformy Xamarin, zobacz dokumentację dotyczącą pracy z tabelami i komórkami dla systemu iOS.

Podsumowanie

W tym artykule omówiono projektowanie widoków tabel i pracę z nimi w aplikacji platformy Xamarin.tvOS. Przedstawiono przykład pracy z widokiem tabeli wewnątrz widoku podziału, który jest typowym użyciem widoku tabeli w aplikacji tvOS.