Compartir a través de


Trabajar con campos de búsqueda y texto de tvOS en Xamarin

Cuando sea necesario, la aplicación Xamarin.tvOS puede solicitar pequeños fragmentos de texto del usuario (como identificadores de usuario y contraseñas) mediante un campo de texto y el teclado en pantalla:

Campo de búsqueda de ejemplo

Opcionalmente, puede proporcionar la capacidad de búsqueda de palabras clave del contenido de la aplicación mediante un campo de búsqueda:

Resultados de la búsqueda de ejemplo

En este documento se tratarán los detalles de cómo trabajar con campos de texto y búsqueda en una aplicación Xamarin.tvOS.

Acerca de los campos de texto y búsqueda

Como se indicó anteriormente, si es necesario, su Xamarin.tvOS puede presentar uno o varios campos de texto para recopilar pequeñas cantidades de texto del usuario mediante un teclado en pantalla (o un teclado bluetooth opcional en función de la versión de tvOS que el usuario haya instalado).

Además, si la aplicación presenta grandes cantidades de contenido al usuario (como una colección de música, películas o imágenes), es posible que quiera incluir un campo de búsqueda que permita al usuario escribir una pequeña cantidad de texto para filtrar la lista de elementos disponibles.

Campos de texto

En tvOS, un campo de texto se presenta como un cuadro de entrada de esquina redondeada y fija que abrirá un teclado en pantalla cuando el usuario haga clic en él:

Campos de texto en tvOS

Cuando el usuario desplaza el Foco a un campo de texto determinado, éste se agrandará y mostrará una sombra profunda. Deberá tener esto en cuenta al diseñar la interfaz de usuario, ya que los campos de texto pueden superponerse a otros elementos de la interfaz de usuario cuando están en el foco.

Apple tiene las siguientes sugerencias para trabajar con campos de texto:

  • Usar la entrada de texto con moderación: debido a la naturaleza del teclado en pantalla, escribir secciones largas de texto o rellenar varios campos de texto es tedioso para el usuario. Una mejor solución es limitar la cantidad de entrada de texto mediante listas de selección o botones.
  • Usar sugerencias para comunicar el propósito: el campo de texto puede mostrar el marcador de posición "sugerencias" cuando está vacío. Si procede, use sugerencias para describir el propósito del campo de texto en lugar de una etiqueta independiente.
  • Seleccionar el tipo de teclado predeterminado adecuado: tvOS proporciona varios tipos de teclado diferentes y creados específicamente que puede especificar para el campo de texto. Por ejemplo, el teclado de dirección de correo electrónico puede facilitar la entrada al permitir que el usuario seleccione de una lista de direcciones escritas recientemente.
  • Cuando proceda, usar campos de texto seguro: un campo de texto seguro presenta los caracteres especificados como puntos (en lugar de las letras reales). Use siempre un campo de texto seguro al recopilar información confidencial, como contraseñas.

Teclados

Cada vez que el usuario hace clic en un campo de texto en la interfaz de usuario, se muestra un teclado lineal en pantalla. El usuario usa la superficie táctil del Control remoto de Siri para seleccionar letras individuales del teclado y escribir la información solicitada:

Teclado remoto de Siri

Si hay más de un campo de texto en la vista actual, se mostrará automáticamente un botón Siguiente para llevar al usuario al siguiente campo de texto. Aparecerá un botón Listo para el último campo de texto que finalizará la introducción de texto y devolverá al usuario a la pantalla anterior.

En cualquier momento, el usuario también puede pulsar el botón Menú del Control remoto de Siri para finalizar la introducción de texto y volver de nuevo a la pantalla anterior.

Apple tiene las siguientes sugerencias para trabajar con teclados en pantalla:

  • Seleccionar el tipo de teclado predeterminado adecuado: tvOS proporciona varios tipos de teclado diferentes y creados específicamente que puede especificar para el campo de texto. Por ejemplo, el teclado de dirección de correo electrónico puede facilitar la entrada al permitir que el usuario seleccione de una lista de direcciones escritas recientemente.
  • Cuando sea apropiado, usar Vistas complementarias del teclado: además de la información estándar que siempre se muestra, pueden agregarse vistas complementarias opcionales (como imágenes o etiquetas) al teclado en pantalla para aclarar el propósito de la entrada de texto o para ayudar al usuario a escribir la información requerida.

Para más información sobre cómo trabajar con el teclado en pantalla, consulte la documentación de Apple UIKeyboardType, Administración del teclado, Vistas personalizadas para la introducción de datos y Guía de programación de texto para iOS.

Un campo de búsqueda presenta una pantalla especializada que proporciona un campo de texto y un teclado en pantalla que permite al usuario filtrar una colección de elementos que se muestran debajo del teclado:

Resultados de búsqueda de ejemplo

A medida que el usuario escribe letras en el campo de búsqueda, los resultados siguientes reflejarán automáticamente los resultados de la búsqueda. En cualquier momento, el usuario puede desplazar el Foco a los resultados y seleccionar uno de los elementos presentados.

Apple tiene las siguientes sugerencias para trabajar con campos de búsqueda:

  • Proporcionar búsquedas recientes: dado que escribir texto con el Control remoto de Siri puede resultar tedioso y los usuarios tienden a repetir las solicitudes de búsqueda, considere la posibilidad de añadir una sección de Resultados de búsqueda recientes antes de los resultados actuales, debajo del área del teclado.
  • Cuando sea posible, limitar el número de resultados: dado que una lista grande de elementos puede ser difícil para que el usuario analice y navegue, considere la posibilidad de limitar el número de resultados devueltos.
  • Si procede, proporcionar filtros de resultados de búsqueda: si el contenido proporcionado por la aplicación se presta, considere la posibilidad de agregar barras de ámbito para permitir al usuario filtrar aún más los resultados de búsqueda devueltos.

Para más información, consulte la Referencia de la clase UISearchController de Apple.

Trabajar con campos de texto

La manera más fácil de trabajar con campos de texto en una aplicación de Xamarin.tvOS es agregarlos al diseño de la interfaz de usuario mediante el Diseñador de iOS.

Haga lo siguiente:

  1. Haga doble clic en el archivo Main.storyboard en el Panel de solución para abrirlo para su edición.

  2. Arrastre uno o más Campos de texto a la superficie de diseño sobre una Vista:

    Un campo de texto

  3. Seleccione los Campos de texto y asigne a cada uno un Nombre único en la pestaña Widget del Panel de propiedades:

    La pestaña Widget del Panel de propiedades

  4. En la sección Campo de texto, puede definir elementos como la sugerencia de Marcador de posición y el Valor predeterminado:

    La sección Campo de texto

  5. Desplácese hacia abajo para definir propiedades como Corrección ortográfica, Mayúsculas y el valor predeterminado de Tipo de teclado:

    Spell Check, mayúsculas y tipo de teclado predeterminado

  6. Guarde los cambios en el Guión gráfico.

En el código, puede obtener o establecer el valor de un campo de texto mediante su propiedad Text:

Console.WriteLine ("User ID {0} and Password {1}", UserId.Text, Password.Text);

Opcionalmente puede usar los eventos de campo de texto Started y Ended para responder al inicio y fin de la entrada de texto.

Trabajar con campos de búsqueda

La manera más fácil de trabajar con campos de búsqueda en una aplicación de Xamarin.tvOS es agregarlos al diseño de la interfaz de usuario mediante el Diseñador de interfaces.

Haga lo siguiente:

  1. Haga doble clic en el archivo Main.storyboard en el Panel de solución para abrirlo para su edición.

  2. Arrastre un nuevo controlador de vista de colección al guión gráfico para presentar los resultados de la búsqueda del usuario:

    Un controlador de vista de colección

  3. En la pestaña Widget del Panel de propiedades, use SearchResultsViewController para la Clase y SearchResults para el Id. del guion gráfico:

    La pestaña Widget de Visual Studio para Mac, donde puede especificar la clase y el Storyboard I D.

  4. Seleccione el Prototipo de celda en la superficie de diseño.

  5. En la pestaña Widget del Explorador de propiedades, use SearchResultCell para la Clase y ImageCell para el Identificador:

    La pestaña Widget de Visual Studio para Mac, donde puede especificar Clase e Identificador.

  6. Componga el diseño del Prototipo de celda y exponga cada elemento con un Nombre único en la pestaña Widget del Explorador de propiedades:

    Diseño del diseño del prototipo de celda

  7. Guarde los cambios en el Guión gráfico.

Proporcionar un modelo de datos

A continuación, deberá proporcionar una clase para que actúe como modelo de datos para los resultados que el usuario va a buscar. En el Explorador de soluciones, haga clic con el botón derecho en el Nombre del proyecto y seleccione Agregar>Nuevo archivo...>General>Clase vacía y proporcione un Nombre:

Seleccione Clase vacía y proporcione un nombre

Por ejemplo, una aplicación que permite al usuario buscar una colección de imágenes por título y palabra clave podría ser similar a la siguiente:

using System;
using Foundation;

namespace tvText
{
    public class PictureInformation : NSObject
    {
        #region Computed Properties
        public string Title { get; set;}
        public string ImageName { get; set;}
        public string Keywords { get; set;}
        #endregion

        #region Constructors
        public PictureInformation (string title, string imageName, string keywords)
        {
            // Initialize
            this.Title = title;
            this.ImageName = imageName;
            this.Keywords = keywords;
        }
        #endregion
    }
}

Celda de vista de colección

Con el modelo de datos en su sitio, edite la Celda de prototipo (SearchResultViewCell.cs) y haga que tenga el siguiente aspecto:

using Foundation;
using System;
using UIKit;

namespace tvText
{
    public partial class SearchResultViewCell : UICollectionViewCell
    {
        #region Private Variables
        private PictureInformation _pictureInfo = null;
        #endregion

        #region Computed Properties
        public PictureInformation PictureInfo {
            get { return _pictureInfo; }
            set {
                _pictureInfo = value;
                UpdateUI ();
            }
        }
        #endregion

        #region Constructors
        public SearchResultViewCell (IntPtr handle) : base (handle)
        {
            // Initialize
            UpdateUI ();
        }
        #endregion

        #region Private Methods
        private void UpdateUI ()
        {
            // Anything to process?
            if (PictureInfo == null) return;

            try {
                Picture.Image = UIImage.FromBundle (PictureInfo.ImageName);
                Picture.AdjustsImageWhenAncestorFocused = true;
                Title.Text = PictureInfo.Title;
                TextColor = UIColor.LightGray;
            } catch {
                // Ignore errors if view isn't fully loaded
            }
        }
        #endregion
    }

}

El método UpdateUI se usará para mostrar campos individuales de los elementos PictureInformation (la propiedad PictureInfo) en los elementos de la interfaz de usuario nombrados cada vez que se actualice la propiedad. Por ejemplo, la imagen y el título asociados a la imagen.

Controlador de vista de colección

A continuación, edite el controlador de vista de la colección de resultados de búsqueda (SearchResultsViewController.cs) y haga que tenga el siguiente aspecto:

using Foundation;
using System;
using UIKit;
using System.Collections.Generic;

namespace tvText
{
    public partial class SearchResultsViewController : UICollectionViewController , IUISearchResultsUpdating
    {
        #region Constants
        public const string CellID = "ImageCell";
        #endregion

        #region Private Variables
        private string _searchFilter = "";
        #endregion

        #region Computed Properties
        public List<PictureInformation> AllPictures { get; set;}
        public List<PictureInformation> FoundPictures { get; set; }
        public string SearchFilter {
            get { return _searchFilter; }
            set {
                _searchFilter = value.ToLower();
                FindPictures ();
                CollectionView?.ReloadData ();
            }
        }
        #endregion

        #region Constructors
        public SearchResultsViewController (IntPtr handle) : base (handle)
        {
            // Initialize
            this.AllPictures = new List<PictureInformation> ();
            this.FoundPictures = new List<PictureInformation> ();
            PopulatePictures ();
            FindPictures ();

        }
        #endregion

        #region Private Methods
        private void PopulatePictures ()
        {
            // Clear list
            AllPictures.Clear ();

            // Add images
            AllPictures.Add (new PictureInformation ("Antipasta Platter","Antipasta","cheese,grapes,tomato,coffee,meat,plate"));
            AllPictures.Add (new PictureInformation ("Cheese Plate", "CheesePlate", "cheese,plate,bread"));
            AllPictures.Add (new PictureInformation ("Coffee House", "CoffeeHouse", "coffee,people,menu,restaurant,cafe"));
            AllPictures.Add (new PictureInformation ("Computer and Expresso", "ComputerExpresso", "computer,coffee,expresso,phone,notebook"));
            AllPictures.Add (new PictureInformation ("Hamburger", "Hamburger", "meat,bread,cheese,tomato,pickle,lettus"));
            AllPictures.Add (new PictureInformation ("Lasagna Dinner", "Lasagna", "salad,bread,plate,lasagna,pasta"));
            AllPictures.Add (new PictureInformation ("Expresso Meeting", "PeopleExpresso", "people,bag,phone,expresso,coffee,table,tablet,notebook"));
            AllPictures.Add (new PictureInformation ("Soup and Sandwich", "SoupAndSandwich", "soup,sandwich,bread,meat,plate,tomato,lettus,egg"));
            AllPictures.Add (new PictureInformation ("Morning Coffee", "TabletCoffee", "tablet,person,man,coffee,magazine,table"));
            AllPictures.Add (new PictureInformation ("Evening Coffee", "TabletMagCoffee", "tablet,magazine,coffee,table"));
        }

        private void FindPictures ()
        {
            // Clear list
            FoundPictures.Clear ();

            // Scan each picture for a match
            foreach (PictureInformation picture in AllPictures) {
                if (SearchFilter == "") {
                    // If no search term, everything matches
                    FoundPictures.Add (picture);
                } else if (picture.Title.Contains (SearchFilter) || picture.Keywords.Contains (SearchFilter)) {
                    // If the search term is in the title or keywords, we've found a match
                    FoundPictures.Add (picture);
                }
            }
        }
        #endregion

        #region Override Methods
        public override nint NumberOfSections (UICollectionView collectionView)
        {
            // Only one section in this collection
            return 1;
        }

        public override nint GetItemsCount (UICollectionView collectionView, nint section)
        {
            // Return the number of matching pictures
            return FoundPictures.Count;
        }

        public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath)
        {
            // Get a new cell and return it
            var cell = collectionView.DequeueReusableCell (CellID, indexPath);
            return (UICollectionViewCell)cell;
        }

        public override void WillDisplayCell (UICollectionView collectionView, UICollectionViewCell cell, NSIndexPath indexPath)
        {
            // Grab the cell
            var currentCell = cell as SearchResultViewCell;
            if (currentCell == null)
                throw new Exception ("Expected to display a `SearchResultViewCell`.");

            // Display the current picture info in the cell
            var item = FoundPictures [indexPath.Row];
            currentCell.PictureInfo = item;
        }

        public override void ItemSelected (UICollectionView collectionView, NSIndexPath indexPath)
        {
            // If this Search Controller was presented as a modal view, close
            // it before continuing
            // DismissViewController (true, null);

            // Grab the picture being selected and report it
            var picture = FoundPictures [indexPath.Row];
            Console.WriteLine ("Selected: {0}", picture.Title);
        }

        public void UpdateSearchResultsForSearchController (UISearchController searchController)
        {
            // Save the search filter and update the Collection View
            SearchFilter = searchController.SearchBar.Text ?? string.Empty;
        }

        public override void DidUpdateFocus (UIFocusUpdateContext context, UIFocusAnimationCoordinator coordinator)
        {
            var previousItem = context.PreviouslyFocusedView as SearchResultViewCell;
            if (previousItem != null) {
                UIView.Animate (0.2, () => {
                    previousItem.TextColor = UIColor.LightGray;
                });
            }

            var nextItem = context.NextFocusedView as SearchResultViewCell;
            if (nextItem != null) {
                UIView.Animate (0.2, () => {
                    nextItem.TextColor = UIColor.Black;
                });
            }
        }
        #endregion
    }
}

En primer lugar, la interfaz de IUISearchResultsUpdating se agrega a la clase para agregar el filtro del controlador de búsqueda que actualiza el usuario:

public partial class SearchResultsViewController : UICollectionViewController , IUISearchResultsUpdating

También se define una constante para especificar el id. de la Celda de prototipo (que coincide con el id. definido anteriormente en el Diseñador de interfaz) que se usará más adelante cuando el controlador de colección solicite una nueva celda:

public const string CellID = "ImageCell";

Se crea almacenamiento para la lista completa de elementos buscados, el término del filtro de búsqueda y la lista de elementos que coinciden con ese término:

private string _searchFilter = "";
...

public List<PictureInformation> AllPictures { get; set;}
public List<PictureInformation> FoundPictures { get; set; }
public string SearchFilter {
    get { return _searchFilter; }
    set {
        _searchFilter = value.ToLower();
        FindPictures ();
        CollectionView?.ReloadData ();
    }
}

Cuando se cambia el SearchFilter, se actualiza la lista de elementos coincidentes y se vuelve a cargar el contenido de la vista de colección. La rutina FindPictures es responsable de buscar elementos que coincidan con el nuevo término de búsqueda:

private void FindPictures ()
{
    // Clear list
    FoundPictures.Clear ();

    // Scan each picture for a match
    foreach (PictureInformation picture in AllPictures) {
        if (SearchFilter == "") {
            // If no search term, everything matches
            FoundPictures.Add (picture);
        } else if (picture.Title.Contains (SearchFilter) || picture.Keywords.Contains (SearchFilter)) {
            // If the search term is in the title or keywords, we've found a match
            FoundPictures.Add (picture);
        }
    }
}

El valor del SearchFilter se actualizará (lo que actualizará la vista de colección de resultados) cuando el usuario cambie el filtro en el controlador de búsqueda:

public void UpdateSearchResultsForSearchController (UISearchController searchController)
{
    // Save the search filter and update the Collection View
    SearchFilter = searchController.SearchBar.Text ?? string.Empty;
}

El método PopulatePictures rellena inicialmente la colección de elementos disponibles:

private void PopulatePictures ()
{
    // Clear list
    AllPictures.Clear ();

    // Add images
    AllPictures.Add (new PictureInformation ("Antipasta Platter","Antipasta","cheese,grapes,tomato,coffee,meat,plate"));
    ...
}

Para este ejemplo, todos los datos de ejemplo se crean en memoria cuando se carga el controlador de vista de colección. En una aplicación real, estos datos se leerían probablemente de una base de datos o de un servicio web, y solo en la medida necesaria para no saturar la limitada memoria de Apple TV.

Los métodos NumberOfSections y GetItemsCount proporcionan el número de elementos coincidentes:

public override nint NumberOfSections (UICollectionView collectionView)
{
    // Only one section in this collection
    return 1;
}

public override nint GetItemsCount (UICollectionView collectionView, nint section)
{
    // Return the number of matching pictures
    return FoundPictures.Count;
}

El método GetCell devuelve una nueva Celda de prototipo (basada en la CellID definida anteriormente en el guion gráfico) para cada elemento de la vista de colección:

public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath)
{
    // Get a new cell and return it
    var cell = collectionView.DequeueReusableCell (CellID, indexPath);
    return (UICollectionViewCell)cell;
}

Se llama al método WillDisplayCell antes de que se muestre la celda para que se pueda configurar:

public override void WillDisplayCell (UICollectionView collectionView, UICollectionViewCell cell, NSIndexPath indexPath)
{
    // Grab the cell
    var currentCell = cell as SearchResultViewCell;
    if (currentCell == null)
        throw new Exception ("Expected to display a `SearchResultViewCell`.");

    // Display the current picture info in the cell
    var item = FoundPictures [indexPath.Row];
    currentCell.PictureInfo = item;
}

El método DidUpdateFocus proporciona comentarios visuales al usuario a medida que resaltan elementos en la vista de colección de resultados:

public override void DidUpdateFocus (UIFocusUpdateContext context, UIFocusAnimationCoordinator coordinator)
{
    var previousItem = context.PreviouslyFocusedView as SearchResultViewCell;
    if (previousItem != null) {
        UIView.Animate (0.2, () => {
            previousItem.TextColor = UIColor.LightGray;
        });
    }

    var nextItem = context.NextFocusedView as SearchResultViewCell;
    if (nextItem != null) {
        UIView.Animate (0.2, () => {
            nextItem.TextColor = UIColor.Black;
        });
    }
}

Por último, el método ItemSelected controla el usuario seleccionando un elemento (haciendo clic en la superficie táctil con el control remoto de Siri) en la vista colección de resultados:

public override void ItemSelected (UICollectionView collectionView, NSIndexPath indexPath)
{
    // If this Search Controller was presented as a modal view, close
    // it before continuing
    // DismissViewController (true, null);

    // Grab the picture being selected and report it
    var picture = FoundPictures [indexPath.Row];
    Console.WriteLine ("Selected: {0}", picture.Title);
}

Si el campo de búsqueda se presentó como una vista de diálogo modal (por encima de la vista que lo llama), use el método DismissViewController para descartar la vista de búsqueda cuando el usuario seleccione un elemento. En este ejemplo, el campo de búsqueda se presenta como el contenido de una pestaña Vista de pestaña, por lo que no se descarta aquí.

Para más información sobre las vistas de colección, consulte nuestra documentación Trabajar con vistas de colección.

Presentación del campo de búsqueda

Existen dos formas principales de presentar al usuario un campo de búsqueda (y su teclado en pantalla y resultados de búsqueda asociados) en tvOS:

  • Vista de diálogo modal: el campo de búsqueda puede presentarse sobre la vista y el controlador de vista actuales como una vista de diálogo modal a pantalla completa. Esto suele hacerse en respuesta al usuario que hace clic en un botón u otro elemento de la interfaz de usuario. El cuadro de diálogo se descarta cuando el usuario selecciona un elemento de los resultados de la búsqueda.
  • Ver contenido: el campo de búsqueda es una parte directa de una vista determinada. Por ejemplo, como contenido de una pestaña de búsqueda en un controlador de vista de pestañas.

Para el ejemplo de una lista de imágenes en la que se pueden realizar búsquedas dado anteriormente, el campo de búsqueda se presenta como contenido de la vista en la pestaña de búsqueda y el controlador de la vista de la pestaña de búsqueda tiene el siguiente aspecto:

using System;
using UIKit;

namespace tvText
{
    public partial class SecondViewController : UIViewController
    {
        #region Constants
        public const string SearchResultsID = "SearchResults";
        #endregion

        #region Computed Properties
        public SearchResultsViewController ResultsController { get; set;}
        #endregion

        #region Constructors
        public SecondViewController (IntPtr handle) : base (handle)
        {
        }
        #endregion

        #region Private Methods
        public void ShowSearchController ()
        {
            // Build an instance of the Search Results View Controller from the Storyboard
            ResultsController = Storyboard.InstantiateViewController (SearchResultsID) as SearchResultsViewController;
            if (ResultsController == null)
                throw new Exception ("Unable to instantiate a SearchResultsViewController.");

            // Create an initialize a new search controller
            var searchController = new UISearchController (ResultsController) {
                SearchResultsUpdater = ResultsController,
                HidesNavigationBarDuringPresentation = false
            };

            // Set any required search parameters
            searchController.SearchBar.Placeholder = "Enter keyword (e.g. coffee)";

            // The Search Results View Controller can be presented as a modal view
            // PresentViewController (searchController, true, null);

            // Or in the case of this sample, the Search View Controller is being
            // presented as the contents of the Search Tab directly. Use either one
            // or the other method to display the Search Controller (not both).
            var container = new UISearchContainerViewController (searchController);
            var navController = new UINavigationController (container);
            AddChildViewController (navController);
            View.Add (navController.View);
        }
        #endregion

        #region Override Methods
        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();

            // If the Search Controller is being displayed as the content
            // of the search tab, include it here.
            ShowSearchController ();
        }

        public override void ViewDidAppear (bool animated)
        {
            base.ViewDidAppear (animated);

            // If the Search Controller is being presented as a modal view,
            // call it here to display it over the contents of the Search
            // tab.
            // ShowSearchController ();
        }
        #endregion
    }
}

En primer lugar, se define una constante que coincide con el Identificador de guion gráfico que se asignó al controlador de la vista de colección de resultados de búsqueda en el Diseñador de interfaz:

public const string SearchResultsID = "SearchResults";

A continuación, el método ShowSearchController crea un nuevo controlador de la colección de vistas de búsqueda y muestra que era necesario:

public void ShowSearchController ()
{
    // Build an instance of the Search Results View Controller from the Storyboard
    ResultsController = Storyboard.InstantiateViewController (SearchResultsID) as SearchResultsViewController;
    if (ResultsController == null)
        throw new Exception ("Unable to instantiate a SearchResultsViewController.");

    // Create an initialize a new search controller
    var searchController = new UISearchController (ResultsController) {
        SearchResultsUpdater = ResultsController,
        HidesNavigationBarDuringPresentation = false
    };

    // Set any required search parameters
    searchController.SearchBar.Placeholder = "Enter keyword (e.g. coffee)";

    // The Search Results View Controller can be presented as a modal view
    // PresentViewController (searchController, true, null);

    // Or in the case of this sample, the Search View Controller is being
    // presented as the contents of the Search Tab directly. Use either one
    // or the other method to display the Search Controller (not both).
    var container = new UISearchContainerViewController (searchController);
    var navController = new UINavigationController (container);
    AddChildViewController (navController);
    View.Add (navController.View);
}

En el método anterior, una vez que se ha instanciado un SearchResultsViewController del guión gráfico, se crea un nuevo UISearchController para presentar al usuario el campo de búsqueda y el teclado en pantalla. La colección Resultados de búsqueda (tal como se define en el SearchResultsViewController) se mostrará en este teclado.

A continuación, el SearchBar se configura con información como la sugerencia de Marcador de posición. Esto proporciona información al usuario sobre el tipo de búsqueda que se está realizando.

A continuación, el campo de búsqueda se presenta al usuario de una de estas dos maneras:

  • Vista de diálogo modal: se llama al método PresentViewController para presentar la búsqueda sobre la vista existente, a pantalla completa.
  • Ver contenido: se crea un UISearchContainerViewController para contener el controlador de búsqueda. Se crea un UINavigationController para contener el contenedor de búsqueda y, a continuación, el controlador de navegación se agrega al controlador de vista AddChildViewController (navController) y la vista presentada View.Add (navController.View).

Por último, y de nuevo en función del tipo de presentación, el método ViewDidLoad o ViewDidAppear llamará al método ShowSearchController para presentar la búsqueda al usuario:

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();

    // If the Search Controller is being displayed as the content
    // of the search tab, include it here.
    ShowSearchController ();
}

public override void ViewDidAppear (bool animated)
{
    base.ViewDidAppear (animated);

    // If the Search Controller is being presented as a modal view,
    // call it here to display it over the contents of the Search
    // tab.
    // ShowSearchController ();
}

Cuando se ejecute la aplicación y el usuario seleccione la pestaña Buscar, se le presentará la lista completa de elementos sin filtrar:

Resultados de búsqueda predeterminados

Cuando el usuario empiece a escribir un término de búsqueda, la lista de resultados se filtrará por ese término y se actualizará automáticamente:

Resultados de la búsqueda filtrados

En cualquier momento, el usuario puede cambiar el foco a un elemento de los resultados de búsqueda y hacer clic en la superficie táctil del Control remoto de Siri para seleccionarlo.

Resumen

En este artículo se ha tratado el diseño y el trabajo con campos de texto y de búsqueda dentro de una aplicación de Xamarin.tvOS. Ha mostrado cómo crear contenidos de texto y de colección de búsqueda en el Diseñador de interfaz y ha mostrado dos formas distintas de presentar un campo de búsqueda al usuario en tvOS.