Partilhar via


Trabalhando com campos de texto e pesquisa do tvOS no Xamarin

Quando necessário, seu aplicativo Xamarin.tvOS pode solicitar pequenos trechos de texto do usuário (como IDs de usuário e senhas) usando um campo de texto e o teclado na tela:

Campo de pesquisa de exemplo

Opcionalmente, você pode fornecer a capacidade de pesquisa de palavra-chave do conteúdo do aplicativo usando um Campo de Pesquisa:

Resultados da pesquisa de exemplo

Este documento abordará os detalhes do trabalho com Campos de Texto e Pesquisa em um aplicativo Xamarin.tvOS.

Sobre campos de texto e pesquisa

Como dito acima, se necessário, seu Xamarin.tvOS pode apresentar um ou mais campos de texto para coletar pequenas quantidades de texto do usuário usando um teclado bluetooth na tela (ou teclado bluetooth opcional, dependendo da versão do tvOS que o usuário instalou).

Além disso, se seu aplicativo apresentar grandes quantidades de conteúdo para o usuário (como uma música, filmes ou uma coleção de imagens), convém incluir um Campo de Pesquisa que permita ao usuário inserir uma pequena quantidade de texto para filtrar a lista de itens disponíveis.

Campos de Texto

No tvOS, um Campo de Texto é apresentado como uma caixa de entrada de altura fixa e canto arredondado que abrirá um teclado na tela quando o usuário clicar nele:

Campos de texto no tvOS

Quando o usuário move o Foco para um determinado Campo de Texto, ele aumenta e exibe uma sombra profunda. Você precisará ter isso em mente ao projetar sua Interface do Usuário, pois os Campos de Texto podem se sobrepor a outros elementos da interface do usuário quando estiverem em foco.

A Apple tem as seguintes sugestões para trabalhar com campos de texto:

  • Use a entrada de texto com moderação - Devido à natureza do teclado na tela, inserir longas seções de texto ou preencher vários campos de texto é tedioso para o usuário. Uma solução melhor é limitar a quantidade de entrada de texto usando listas de seleção ou botões.
  • Usar dicas para comunicar a finalidade - O campo de texto pode exibir "dicas" de espaço reservado quando vazio. Quando aplicável, use dicas para descrever a finalidade do seu Campo de Texto em vez de um Rótulo separado.
  • Selecione o Tipo de teclado padrão apropriado - o tvOS fornece vários tipos de teclado diferentes criados especificamente que você pode especificar para seu campo de texto. Por exemplo, o Teclado de Endereço de Email pode facilitar a entrada, permitindo que o usuário selecione em uma lista de endereços inseridos recentemente.
  • Quando apropriado, use Campos de Texto Seguros - Um Campo de Texto Seguro apresenta os caracteres inseridos como pontos (em vez das letras reais). Sempre use um Campo de Texto Seguro ao coletar informações confidenciais, como senhas.

Teclados

Sempre que o usuário clica em um campo de texto na interface do usuário, um teclado linear na tela é exibido. O usuário usa o Touch Surface the Siri Remote para selecionar letras individuais do teclado e inserir as informações solicitadas:

O teclado Siri Remote

Se houver mais de um Campo de Texto no modo de exibição atual, um botão Avançar será exibido automaticamente para levar o usuário ao próximo Campo de Texto. Um botão Concluído será exibido para o último Campo de Texto que encerrará a entrada de texto e retornará o usuário à tela anterior.

A qualquer momento, o usuário também pode pressionar o botão Menu no Siri Remote para encerrar a entrada de texto e retornar novamente à tela anterior.

A Apple tem as seguintes sugestões para trabalhar com teclados no ecrã:

  • Selecione o Tipo de teclado padrão apropriado - o tvOS fornece vários tipos de teclado diferentes criados especificamente que você pode especificar para seu campo de texto. Por exemplo, o Teclado de Endereço de Email pode facilitar a entrada, permitindo que o usuário selecione em uma lista de endereços inseridos recentemente.
  • Quando apropriado, use Modos de Exibição de Acessórios do Teclado - Além das informações padrão que são sempre exibidas, as Exibições de Acessórios opcionais (como Imagens ou Rótulos) podem ser adicionadas ao teclado na tela para esclarecer a finalidade da entrada de texto ou para ajudar o usuário a inserir as informações necessárias.

Para obter mais informações sobre como trabalhar com o teclado na tela, consulte a documentação do iOS UIKeyboardType da Apple, Gerenciando o teclado, visualizações personalizadas para entrada de dados e programação de texto.

Um Campo de Pesquisa apresenta uma tela especializada que fornece um Campo de Texto e um teclado na tela que permite ao usuário filtrar uma coleção de itens que são exibidos abaixo do teclado:

Resultados de pesquisa de exemplo

À medida que o usuário insere letras no Campo de Pesquisa, os resultados abaixo refletirão automaticamente os resultados da pesquisa. A qualquer momento, o usuário pode mudar o foco para os resultados e selecionar um dos itens apresentados.

A Apple tem as seguintes sugestões para trabalhar com campos de pesquisa:

  • Fornecer pesquisas recentes - Como inserir texto com o Siri Remote pode ser tedioso e os usuários tendem a repetir solicitações de pesquisa, considere adicionar uma seção de Resultados de pesquisa recentes antes dos resultados atuais na área do teclado.
  • Quando possível, limitar o número de resultados - Como uma grande lista de itens pode ser difícil para o usuário analisar e navegar, considere limitar o número de resultados retornados.
  • Se apropriado, Fornecer filtros de resultados de pesquisa - Se o conteúdo fornecido pelo seu aplicativo se prestar, considere adicionar barras de escopo para permitir que o usuário filtre ainda mais os resultados da pesquisa retornados.

Para obter mais informações, consulte a Referência de classe UISearchController da Apple.

Trabalhando com campos de texto

A maneira mais fácil de trabalhar com campos de texto em um aplicativo Xamarin.tvOS é adicioná-los ao design da Interface do Usuário usando o iOS Designer.

Faça o seguinte:

  1. No Solution Pad, clique duas vezes no Main.storyboard arquivo para abri-lo para edição.

  2. Arraste um ou mais Campos de Texto na superfície de design para um Modo de Exibição:

    Um campo de texto

  3. Selecione os Campos de Texto e dê a cada um um Nome exclusivo na guia Widget do Bloco de Propriedades:

    A guia Widget do Bloco de Propriedades

  4. Na seção Campo de Texto, você pode definir elementos como a dica de Espaço reservado e o Valor padrão:

    A seção Campo de texto

  5. Role para baixo para definir propriedades como Verificação Ortográfica, Capitalização e o Tipo de Teclado padrão:

    Verificação ortográfica, maiúsculas e o tipo de teclado padrão

  6. Salve as alterações no seu Storyboard.

No código, você pode obter ou definir o valor de um campo de texto usando sua Text propriedade:

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

Opcionalmente, você pode usar os Started eventos e Ended Text Field para responder ao início e ao fim da entrada de texto.

Trabalhando com campos de pesquisa

A maneira mais fácil de trabalhar com Campos de Pesquisa em um aplicativo Xamarin.tvOS é adicioná-los ao design da Interface do Usuário usando o Designer de Interface.

Faça o seguinte:

  1. No Solution Pad, clique duas vezes no Main.storyboard arquivo para abri-lo para edição.

  2. Arraste um novo Controlador de Exibição de Coleção para o Storyboard para apresentar os resultados da pesquisa do usuário:

    Um controlador de exibição de coleção

  3. Na guia Widget do Bloco de Propriedades, use SearchResultsViewController para a Classe e SearchResults para a ID do Storyboard:

    A guia Widget no Visual Studio para Mac, onde você pode especificar Classe e Storyboard I D.

  4. Selecione o Protótipo de célula na superfície de design.

  5. Na guia Widget do Gerenciador de Propriedades, use SearchResultCell para a Classe e ImageCell para o Identificador:

    A guia Widget no Visual Studio para Mac, onde você pode especificar Classe e Identificador.

  6. Esquematize o design do Protótipo de Célula e exponha cada elemento com um Nome exclusivo na guia Widget do Gerenciador de Propriedades:

    Layout do design do protótipo da célula

  7. Salve as alterações no seu Storyboard.

Fornecer um modelo de dados

Em seguida, você precisará fornecer uma classe para atuar como o Modelo de Dados para os resultados que o usuário estará procurando. No Gerenciador de Soluções, clique com o botão direito do mouse no Nome do Projeto e selecione Adicionar>Novo Arquivo...>Classe vazia geral>e forneça um nome:

Selecione Classe vazia e forneça um nome

Por exemplo, um aplicativo que permite ao usuário pesquisar uma coleção de Imagens por Título e Palavra-chave pode ter a seguinte aparência:

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

A célula de exibição de coleção

Com o Modelo de Dados no lugar, edite a Célula de Protótipo (SearchResultViewCell.cs) e faça com que ela pareça a seguinte:

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
    }

}

O UpdateUI método será usado para exibir campos individuais dos itens PictureInformation (a PictureInfo propriedade) nos elementos de interface do usuário nomeados sempre que a propriedade for atualizada. Por exemplo, a Imagem e o Título associados à Imagem.

O controlador de exibição de coleção

Em seguida, edite o Controlador de Exibição da Coleção de Resultados da Pesquisa (SearchResultsViewController.cs) e torne-o semelhante ao seguinte:

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

Primeiro, a IUISearchResultsUpdating Interface é adicionada à classe para manipular o filtro do Controlador de Pesquisa que está sendo atualizado pelo usuário:

public partial class SearchResultsViewController : UICollectionViewController , IUISearchResultsUpdating

Uma constante também é definida para especificar a ID da Célula Protótipo (que corresponde à ID definida no Designer de Interface acima) que será usada posteriormente quando o Controlador de Coleção solicitar uma nova Célula:

public const string CellID = "ImageCell";

O armazenamento é criado para a lista completa de itens que estão sendo pesquisados, o termo de filtro de pesquisa e uma lista de itens correspondentes a esse termo:

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

Quando o SearchFilter é alterado, a lista de itens correspondentes é atualizada e o conteúdo do Modo de Exibição de Coleção é recarregado. A FindPictures rotina é responsável por encontrar itens que correspondam ao novo termo de pesquisa:

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

O valor do SearchFilter será atualizado (o que atualizará a Exibição de Coleta de Resultados) quando o usuário alterar o Filtro no Controlador de Pesquisa:

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

O PopulatePictures método inicialmente preenche a coleção de itens disponíveis:

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

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

Para fins deste exemplo, todos os dados de exemplo estão sendo criados na memória quando o Controlador de Exibição de Coleção é carregado. Em um aplicativo real, esses dados provavelmente seriam lidos de um banco de dados ou serviço da Web, e apenas conforme necessário para evitar que a memória limitada da Apple TV ultrapassasse.

Os NumberOfSections métodos e GetItemsCount fornecem o número de itens correspondentes:

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

O GetCell método retorna uma nova célula de protótipo (com base no CellID definido acima no Storyboard) para cada item no modo de exibição de coleção:

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

O WillDisplayCell método é chamado antes da célula ser exibida para que possa ser configurado:

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

O DidUpdateFocus método fornece feedback visual ao usuário à medida que ele realça itens no Modo de Exibição de Coleta 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;
        });
    }
}

Finalmente, o ItemSelected método manipula o usuário selecionando um item (clicando no Touch Surface com o Siri Remote) na Visualização da Coleta 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);
}

Se o Campo de Pesquisa foi apresentado como um modo de exibição de caixa de diálogo modal (na parte superior do modo de exibição chamando-o), use o DismissViewController método para descartar o Modo de Exibição de Pesquisa quando o usuário selecionar um item. Para este exemplo, o Campo de Pesquisa é apresentado como o conteúdo de uma guia Modo de Exibição de Guia, portanto, ele não está sendo descartado aqui.

Para obter mais informações sobre Exibições de Coleção, consulte nossa documentação Trabalhando com Exibições de Coleção .

Apresentando o campo de pesquisa

Há duas maneiras principais que um campo de pesquisa (e seu teclado na tela associado e resultados de pesquisa) pode ser apresentado ao usuário no tvOS:

  • Exibição de caixa de diálogo modal - O campo de pesquisa pode ser apresentado sobre o controlador de exibição e exibição atual como uma exibição de diálogo modal de tela inteira. Isso geralmente é feito em resposta ao usuário clicar em um botão ou outro elemento da interface do usuário. A caixa de diálogo é descartada quando o usuário seleciona um item nos resultados da pesquisa.
  • Exibir conteúdo - O campo de pesquisa é uma parte direta de uma determinada exibição. Por exemplo, como o conteúdo de uma guia Pesquisar em um controlador de exibição de guia.

Para o exemplo de uma lista pesquisável de imagens fornecidas acima, o Campo de Pesquisa é apresentado como Exibir Conteúdo na guia Pesquisar e o Controlador de Exibição da Guia Pesquisar tem a seguinte aparência:

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

Primeiro, é definida uma constante que corresponde ao Identificador de Storyboard que foi atribuído ao controlador de Exibição de Coleta de Resultados de Pesquisa no Designer de Interface:

public const string SearchResultsID = "SearchResults";

Em seguida, o ShowSearchController método cria um novo controlador de coleção de exibição de pesquisa e exibe que era necessário:

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

No método acima, uma vez que um SearchResultsViewController tenha sido instanciado a partir do Storyboard, um novo UISearchController é criado para apresentar o Campo de Pesquisa e o teclado na tela para o usuário. A coleção Resultados da SearchResultsViewControllerPesquisa (conforme definido pelo ) será exibida sob este teclado.

Em seguida, o SearchBar é configurado com informações como a dica de espaço reservado . Isso fornece informações ao usuário sobre o tipo de pesquisa que está sendo pré-formada.

Em seguida, o campo de pesquisa é apresentado ao usuário de duas maneiras:

  • Modal Dialog View - O PresentViewController método é chamado para apresentar a pesquisa sobre o modo de exibição existente, em tela cheia.
  • Exibir conteúdo - A UISearchContainerViewController é criado para conter o controlador de pesquisa. A UINavigationController é criado para conter o Contêiner de Pesquisa, em seguida, o Controlador de Navegação é adicionado ao Controlador de Exibição AddChildViewController (navController)e o Modo de Exibição é apresentado View.Add (navController.View).

Finalmente, e novamente com base no tipo de apresentação, o ViewDidLoad método ou ViewDidAppear chamará o ShowSearchController método para apresentar a pesquisa ao usuário:

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

Quando o aplicativo for executado e a guia Pesquisar selecionada pelo usuário, a lista completa de itens não filtrados será apresentada ao usuário:

Resultados de pesquisa padrão

À medida que o usuário começa a inserir um termo de pesquisa, a lista de resultados será filtrada por esse termo e atualizada automaticamente:

Resultados da pesquisa filtrados

A qualquer momento, o usuário pode alternar o Foco para um item nos resultados da pesquisa e clicar na Superfície de toque do Siri Remote para selecioná-lo.

Resumo

Este artigo abordou o design e o trabalho com campos de texto e pesquisa dentro de um aplicativo Xamarin.tvOS. Ele mostrou como criar conteúdo de Texto e Coleção de Pesquisa no Designer de Interface e mostrou duas maneiras diferentes de um Campo de Pesquisa ser apresentado ao usuário no tvOS.