Trabajar con vistas de tabla tvOS en Xamarin
En este artículo se describe el diseño y el trabajo con vistas de tabla y controladores de vistas de tabla dentro de una aplicación de Xamarin.tvOS.
En tvOS, una vista de tabla se presenta como una sola columna de filas de desplazamiento que se pueden organizar opcionalmente en grupos o secciones. Las vistas de tabla deben usarse cuando necesite mostrar una gran cantidad de datos de forma eficaz para el usuario, de forma clara para comprenderlo.
Las vistas de tabla se muestran normalmente en un lado de una Vista dividida como navegación, con los detalles del elemento seleccionado mostrado en el lado opuesto:
Acerca de las vistas de tabla
Muestra UITableView
una sola columna de filas desplazables como una lista jerárquica de información que se puede organizar opcionalmente en grupos o secciones:
Apple tiene las siguientes sugerencias para trabajar con tablas:
- Tener en cuenta el ancho: Intente alcanzar el equilibrio correcto en los anchos de la tabla. Si la tabla es demasiado ancha, puede ser difícil examinar desde una distancia y puede quitarse del área de contenido disponible. Si la tabla es demasiado estrecha, puede hacer que la información se trunquen o encapsulan, de nuevo esto puede ser difícil para que el usuario lea desde la sala.
- Mostrar contenido de tabla rápidamente: Para listas grandes de datos, cargue el contenido diferida y empiece a mostrar información en cuanto se presente la tabla al usuario. Si la tabla tarda mucho tiempo en cargarse, el usuario podría perder interés en la aplicación o pensar que está bloqueado.
- Informar al usuario de cargas de contenido largo: Si un tiempo de carga de tabla larga es inevitable, presente una Barra de progreso o un indicador de actividad para que sepan que la aplicación no se ha bloqueado.
Tipos de celdas de vista de tabla
UITableViewCell
Se usa para representar las filas de datos individuales en la vista tabla. Apple ha definido varios tipos de celdas de tabla predeterminados:
- Valor predeterminado: Este tipo presenta una opción Imagen en el lado izquierdo de la celda y el título alineado a la izquierda a la derecha.
- Subtítulo: Este tipo presenta un título alineado a la izquierda en la primera línea y un subtítulo alineado a la izquierda más pequeño en la línea siguiente.
- Valor 1: Este tipo presenta un título alineado a la izquierda con un subtítulo alineado a la derecha más claro en la misma línea.
- Valor 2: Este tipo presenta un título alineado a la derecha con un subtítulo de color más claro y alineado a la izquierda en la misma línea.
Todos los tipos de celdas de vista de tabla predeterminados también admiten elementos gráficos como indicadores de divulgación o marcas de verificación.
Además, puede definir un tipo de celda Personalizado vista de tabla y presentar un Prototipo de celda, que se crea en el Diseñador de interfaces o a través del código.
Apple tiene las siguientes sugerencias para trabajar con celdas de vista de tabla:
- Evitar recorte de texto: Mantenga las líneas individuales de texto cortas para que no terminen truncadas. Las palabras o frases truncadas son difíciles para que el usuario analice desde toda la sala.
- Considerar el estado de fila centrado: Dado que una fila se vuelve más grande, con esquinas más redondeadas cuando está en el foco, debe probar la apariencia de la celda en todos los estados. Es posible que las imágenes o el texto se recorten o parezcan incorrectos en el estado Centrado.
- Usar tablas editables con moderación: Mover o eliminar filas de tabla es más lento en tvOS que en iOS. Debe decidir cuidadosamente si esta característica agregará o distrae la aplicación tvOS.
- Crear tipos de celda personalizados cuando proceda: Aunque los tipos de celda integrados de vista de tabla son excelentes para muchas situaciones, considere la posibilidad de crear tipos de celda personalizados para información no estándar para proporcionar un mayor control y presentar mejor la información al usuario.
Trabajar con vistas de tabla
La manera más fácil de trabajar con vistas de tabla en una aplicación de Xamarin.tvOS es crear y modificar su apariencia en el Diseñador de interfaces.
Para comenzar, haga lo siguiente:
En Visual Studio para Mac, inicie un nuevo proyecto de aplicación tvOS y seleccione tvOS>App>Single View App y haga clic en el botón Siguiente:
Escriba un Nombre para la aplicación y haga clic en Siguiente:
Ajuste el Nombre de proyecto y Nombre de solución o acepte los valores predeterminados y haga clic en el botón Crear para crear la nueva solución:
En el Panel de solución, haga doble clic en el
Main.storyboard
archivo para abrirlo en el Diseñador de iOS:Seleccione y elimine el Controlador de vista predeterminado:
Seleccione un Controlador de vista dividido en el Cuadro de herramientas y arrástrelo a la Superficie de diseño.
De forma predeterminada, obtendrá una Vista dividida con un Controlador de vista de navegación y un Controlador de vista de tabla en el lado izquierdo y unControlador de vista en el lado derecho. Este es el uso sugerido de Apple de una vista de tabla en tvOS:
Deberá seleccionar todas las partes de la vista de tabla y asignarle un Nombre de clase personalizadoen la pestaña Widget del Explorador de propiedades para que pueda acceder a ella más adelante en el código de C#. Por ejemplo, el Controlador de vista de tabla:
Asegúrese de crear una clase personalizada para el Controlador de vista de tabla, la Vista de tabla y cualquier Celda prototipo. Visual Studio para Mac agregará las clases personalizadas al árbol de proyectos a medida que se crean:
A continuación, seleccione la Vista de tabla en la Superficie de diseño y ajuste sus propiedades según sea necesario. Por ejemplo, el número de Celdas prototipo y el Estilo (sin formato o agrupado):
Para cada Celda prototipo, selecciónelo y asígnele un Identificadorúnico en la pestaña Widget del Explorador de propiedades. Este paso es muy importante, ya que necesitará este identificador más adelante al rellenar la tabla. Por ejemplo:
AttrCell
También puede seleccionar presentar la celda como una de los Tipos de celda de vista de tabla predeterminada a través de la lista desplegable Estilo o establecerla en Personalizado y usar la Superficie de diseño para diseñar la celda arrastrando en otros widgets de interfaz de usuario desde el Cuadro de herramientas:
Asigne un Nombre únicoa cada elemento de la interfaz de usuario en el diseño de celda prototipo en la pestaña Widget del Explorador de propiedades para que pueda acceder a ellos más adelante en el código de C#:
Repita el paso anterior para todas las celdas prototipo en la vista tabla.
A continuación, asigne clases personalizadas al resto del diseño de la interfaz de usuario, diseñe la vista Detalles y asigne Nombres únicos a cada elemento de la interfaz de usuario de la vista Detalles para poder acceder a ellas también en C#. Por ejemplo:
Guarde los cambios en el guión gráfico.
Diseño de un modelo de datos
Para facilitar el trabajo con la información que mostrará la vista de tabla y facilitar la presentación de información detallada (como el usuario selecciona o resalta filas en la vista tabla), cree una clase o clases personalizadas para que actúen como modelo de datos para la información presentada.
Tome el ejemplo de una aplicación de reserva de viajes que contiene una lista de Ciudades, cada una que contiene una lista única de Atracciones que el usuario puede seleccionar. El usuario podrá marcar una atracción como Favorita, seleccionar para obtener Indicaciones a una atracción y Reservar un vuelo a una ciudad determinada.
Para crear el modelo de datos para una Atracción, haga clic con el botón derecho en el nombre del proyecto en el Panel de solución y seleccione Agregar>Nuevo archivo.... Escriba AttractionInformation
para el Nombre y haga clic en el botón Nuevo:
Edite el archivo AttractionInformation.cs
para que quede de la siguiente manera:
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
}
}
Esta clase proporciona las propiedades para almacenar la información sobre una Atracción determinada.
A continuación, haga clic con el botón derecho en el nombre del proyecto en el Panel de solución de nuevo y seleccione Agregar>Nuevo archivo.... Escriba CityInformation
para el Nombre y haga clic en el botón Nuevo:
Edite el archivo CityInformation.cs
para que quede de la siguiente manera:
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
}
}
Esta clase contiene toda la información sobre una Ciudad de destin, una colección de Atracciones para esa ciudad y proporciona dos métodos auxiliares (AddAttraction
) para facilitar la adición de atracciones a la ciudad.
Origen de datos de vista de tabla
Cada vista de tabla requiere un origen de datos (UITableViewDataSource
) para proporcionar los datos de la tabla y generar las filas necesarias según sea necesario en la vista tabla.
Para el ejemplo anterior, haga clic con el botón derecho en el nombre del proyecto en el Explorador de soluciones, seleccione Agregar>Nuevo archivo... y llámelo AttractionTableDatasource
y haga clic en el botón Nuevo para crear. A continuación, edite el archivo AttractionTableDatasource.cs
y haga que tenga un aspecto similar al siguiente:
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
}
}
Echemos un vistazo a algunas secciones de la clase en detalle.
En primer lugar, hemos definido una constante para contener el identificador único de la celda prototipo (este es el mismo identificador asignado en el Diseñador de interfaces anterior), se ha agregado un acceso directo al controlador de vista de tabla y se ha creado almacenamiento para nuestros datos:
const string CellID = "AttrCell";
public AttractionTableViewController Controller { get; set;}
public List<CityInformation> Cities { get; set;}
A continuación, guardamos el controlador de vista de tabla y, a continuación, compilamos y rellenamos nuestro origen de datos (con los modelos de datos definidos anteriormente) cuando se crea la clase:
public AttractionTableDatasource (AttractionTableViewController controller)
{
// Initialize
this.Controller = controller;
this.Cities = new List<CityInformation> ();
PopulateCities ();
}
Por ejemplo, el método PopulateCities
simplemente crea objetos data Model en memoria, pero estos podrían leerse fácilmente desde una base de datos o un servicio web en una aplicación real:
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");
...
}
El método NumberOfSections
devuelve el número de secciones de la tabla:
public override nint NumberOfSections (UITableView tableView)
{
// Return number of cities
return Cities.Count;
}
Para vistas de tabla con estilo Sin formato, siempre devuelve 1.
El método RowsInSection
devuelve el número de filas de la sección actual:
public override nint RowsInSection (UITableView tableView, nint section)
{
// Return the number of attractions in the given city
return Cities [(int)section].Attractions.Count;
}
De nuevo, para vistas de tabla Sin formato, devuelva el número total de elementos del origen de datos.
El método TitleForHeader
devuelve el título de la sección especificada:
public override string TitleForHeader (UITableView tableView, nint section)
{
// Get the name of the current city
return Cities [(int)section].Name;
}
Para un tipo de vista tabla sin formato, deje el título en blanco (""
).
Por último, cuando lo solicite la vista tabla, cree y rellene una celda prototipo mediante el GetCell
método:
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;
}
Para obtener más información sobre cómo trabajar con, UITableViewDatasource
vea la documentación de UITableViewDatasourcede Apple.
Delegado de vista de tabla
Cada vista de tabla requiere un delegado (UITableViewDelegate
) para responder a la interacción del usuario u otros eventos del sistema en la tabla.
Para el ejemplo anterior, haga clic con el botón derecho en el nombre del proyecto en el Explorador de soluciones, seleccione Agregar>Nuevo archivo... y llámelo AttractionTableDelegate
y haga clic en el botón Nuevo para crear. A continuación, edite el archivo AttractionTableDelegate.cs
y haga que tenga un aspecto similar al siguiente:
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
}
}
Echemos un vistazo a varias secciones de esta clase en detalles.
En primer lugar, creamos un acceso directo al controlador de vista de tabla cuando se crea la clase :
public AttractionTableViewController Controller { get; set;}
...
public AttractionTableDelegate (AttractionTableViewController controller)
{
// Initialize
this.Controller = controller;
}
A continuación, cuando se selecciona una fila (el usuario hace clic en la superficie táctil del Apple Remote) queremos marcar la Atracción representada por la fila seleccionada como favorito:
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 ();
}
A continuación, cuando el usuario resalta una fila (al darle el foco mediante la superficie táctil Apple Remote) queremos presentar los detalles de la Atracción representada por esa fila en la sección Detalles de nuestro controlador de vista dividida:
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);
}
Se llama al método CanFocusRow
para cada fila que está a punto de obtener el foco en la vista de tabla. Devuelve true
si la fila puede obtener el foco; de lo contrario, devuelve false
. En el caso de este ejemplo, hemos creado un evento personalizado AttractionHighlighted
que se generará en cada fila a medida que recibe el foco.
Para obtener más información sobre cómo trabajar con, UITableViewDelegate
vea la documentación de UITableViewDatasourcede Apple.
Celda Vista de tabla
Para cada celda prototipo que agregó a la vista de tabla en el Diseñador de interfaces, también creó una instancia personalizada de la celda vista de tabla (UITableViewCell
) para permitirle rellenar la nueva celda (fila) tal como se crea.
Para la aplicación de ejemplo, haga doble clic en el archivo AttractionTableCell.cs
para abrirlo para su edición y que tenga el siguiente aspecto:
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
}
}
Esta clase proporciona almacenamiento para el objeto del Modelo de Datos de Atracción (AttractionInformation
tal y como se definió anteriormente) que se muestra en la fila determinada:
private AttractionInformation _attraction = null;
...
public AttractionInformation Attraction {
get { return _attraction; }
set {
_attraction = value;
UpdateUI ();
}
}
El UpdateUI
método rellena los Widgets de interfaz de usuario (que se agregaron al prototipo de celda en el Diseñador de interfaces) según sea necesario:
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
}
}
Para obtener más información sobre cómo trabajar con un UITableViewCell
, vea la documentación de UITableViewCell de Apple.
Controlador de vista de tabla
Un controlador de vista de tabla (UITableViewController
) administra una vista de tabla que se ha agregado a un guión gráfico a través del Diseñador de interfaces.
Para la aplicación de ejemplo, haga doble clic en el archivo AttractionTableViewController.cs
para abrirlo para su edición y que tenga el siguiente aspecto:
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
}
}
Echemos un vistazo más detallado a esta clase. En primer lugar, hemos creado accesos directos para facilitar el acceso a la vista de tablaDataSource
y TableDelegate
. Los usaremos más adelante para comunicarse entre la vista de tabla en el lado izquierdo de la vista dividida y la vista detalles de la derecha.
Por último, cuando la vista de tabla se carga en la memoria, creamos instancias de AttractionTableDatasource
y AttractionTableDelegate
(ambas creadas anteriormente) y las adjuntamos a la vista de tabla.
Para obtener más información sobre cómo trabajar con una UITableViewController
, vea la documentación de UITableViewController de Apple.
Extraerlo todo juntos
Como se indica al principio de este documento, las vistas de tabla se muestran normalmente en un lado de un Vista dividida como navegación, con los detalles del elemento seleccionado mostrado en el lado opuesto. Por ejemplo:
Dado que se trata de un patrón estándar en tvOS, echemos un vistazo a los pasos finales para reunir todo y hacer que los lados izquierdo y derecho de la vista dividida interactúen entre sí.
Vista de detalles
Para el ejemplo de la aplicación de viajes presentada anteriormente, se define una clase personalizada (AttractionViewController
) para el controlador de vista estándar que se presenta en el lado derecho de la vista dividida como vista de detalles:
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
}
}
Aquí, se ha proporcionado la Atracción (AttractionInformation
) que se muestra como una propiedad y se ha creado un UpdateUI
método que rellena los Widgets de interfaz de usuario agregados a la vista en el Diseñador de interfaces.
También hemos definido un acceso directo al controlador de vista dividida (SplitView
) que usaremos para comunicar los cambios a la vista de tabla (AcctractionTableView
).
Por último, las acciones personalizadas (eventos) se agregaron a las tres UIButton
instancias creadas en el Diseñador de interfaces, que permiten al usuario marcar una atracción como Favorita, obtener Indicaciones a una atracción y Reservar un vuelo a una ciudad determinada.
Controlador de vista de navegación
Dado que el controlador de vista de tabla está anidado en un controlador de vista de navegación en el lado izquierdo de la vista dividida, el controlador de vista de navegación asignó una clase personalizada (MasterNavigationController
) en el Diseñador de interfaces y se definió de la siguiente manera:
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
}
}
De nuevo, esta clase simplemente define algunos accesos directos para facilitar la comunicación entre los dos lados del controlador de vista dividida:
SplitView
: Es un vínculo al controlador de vista dividida (MainSpiltViewController
) al que pertenece el controlador de vista de navegación.TableController
: Obtiene el controlador de vista de tabla (AttractionTableViewController
) que se presenta como la vista superior en el controlador de vista de navegación.
Controlador de vista dividida
Dado que el controlador de vista dividida es la base de nuestra aplicación, creamos una clase personalizada (MasterSplitViewController
) para ella en el Diseñador de interfaces y la definimos de la siguiente manera:
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
}
}
En primer lugar, creamos accesos directos al lado Detalles de la vista dividida (AttractionViewController
) y al lado del Maestro (MasterNavigationController
). De nuevo, esto facilita la comunicación entre los dos lados más adelante.
A continuación, cuando la vista dividida se carga en la memoria, adjuntamos el controlador de vista dividida a ambos lados de la vista dividida y respondemos al usuario resaltando una atracción en la vista de tabla (AttractionHighlighted
) mostrando la nueva atracción en el lado Detalles de la vista dividida.
Vistas de tabla en detalle
Dado que tvOS se basa en iOS, las vistas de tabla y los controladores de vista de tabla están diseñados y se comportan de forma similar. Para obtener información más detallada sobre cómo trabajar con la vista de tablas en una aplicación de Xamarin, vea nuestra documentación de iOS Trabajar con tablas y celdas.
Resumen
En este artículo se ha tratado el diseño y el trabajo con vistas de tabla dentro de una aplicación Xamarin.tvOS. Y ha presentado un ejemplo de cómo trabajar con una vista de tabla dentro de una vista dividida, que es el uso típico de una vista de tabla en una aplicación tvOS.