Xamarin で tvOS テキスト フィールドと検索フィールドを操作する
必要に応じて、Xamarin.tvOS アプリは、テキスト フィールドとスクリーン キーボードを使用して、ユーザー (ユーザー ID やパスワードなど) に小さなテキストを要求できます。
必要に応じて、検索フィールドを使用してアプリのコンテンツのキーワード検索機能を提供できます。
このドキュメントでは、Xamarin.tvOS アプリでのテキスト フィールドと検索フィールドの操作の詳細について説明します。
テキスト フィールドと検索フィールドについて
前述のように、必要に応じて、Xamarin.tvOS は 1 つ以上のテキスト フィールドを表示して、画面上 (またはユーザーがインストールした tvOS のバージョンによってはオプションの Bluetooth キーボード) を使用してユーザーから少量のテキストを収集できます。
さらに、アプリがユーザーに大量のコンテンツ (音楽、映画、画像コレクションなど) を表示する場合は、ユーザーが少量のテキストを入力して使用可能な項目の一覧をフィルター処理できるようにする検索フィールドを含めることができます。
テキスト フィールド
tvOS では、テキスト フィールドは、高さが固定され、丸みを帯びた角の入力ボックスとして表示され、ユーザーがクリックしたときにスクリーン キーボードが表示されます。
ユーザーが特定のテキスト フィールドにフォーカスを移動すると、大きくなり、深い影が表示されます。 ユーザー インターフェイスを設計するときは、この点に留意する必要があります。テキスト フィールドはフォーカスがあるときに他の UI 要素と重なることがあるためです。
Apple は、テキスト フィールドの操作に関して次のように推奨しています。
- テキスト入力を控えめに使用する - スクリーン キーボードの性質上、長いテキストを入力したり、複数のテキスト フィールドに入力したりするのはユーザーにとって面倒です。 より良い解決策は、選択リストまたはボタンを使用してテキスト入力の量を制限することです。
- ヒントを使用して目的を伝える - テキスト フィールドは、空の場合に "ヒント" というプレースホルダーを表示できます。 適用可能であれば、別のラベルではなくヒントを使用して、テキスト フィールドの目的を説明します。
- 適切な既定のキーボードの種類を選択する - tvOS には、テキスト フィールドに指定できる目的別の組み込みキーボードの種類がいくつか用意されています。 たとえば、電子メール アドレス キーボードは、ユーザーが最近入力したアドレスの一覧から選択できるようにすることで、入力を容易にすることができます。
- 必要に応じて、セキュリティで保護されたテキスト フィールドを使用する - セキュリティで保護されたテキスト フィールドには、入力された文字が (実際の文字ではなく) ドットとして表示されます。 パスワードなどの機密情報を収集するときは、常にセキュリティで保護されたテキスト フィールドを使用します。
キーボード
ユーザーがユーザー インターフェイスのテキスト フィールドをクリックするたびに、線形のスクリーン キーボードが表示されます。 ユーザーは Siri Remote の Touch サーフェスを使用して、キーボードから個々の文字を選択し、要求された情報を入力します。
現在のビューに複数のテキスト フィールドがある場合は、[次へ] ボタンが自動的に表示され、ユーザーは次のテキスト フィールドに移動します。 最後のテキスト フィールドには [完了] ボタンが表示されます。これにより、テキスト入力が終了し、ユーザーが前の画面に戻ります。
ユーザーはいつでも Siri Remote の[MENU] ボタンを押してテキスト入力を終了し、もう一度前の画面に戻ることもできます。
Apple は、スクリーン キーボードの操作に関して次のように推奨しています。
- 適切な既定のキーボードの種類を選択する - tvOS には、テキスト フィールドに指定できる目的別の組み込みキーボードの種類がいくつか用意されています。 たとえば、電子メール アドレス キーボードは、ユーザーが最近入力したアドレスの一覧から選択できるようにすることで、入力を容易にすることができます。
- 必要に応じて、キーボード アクセサリ ビューを使用する - 常に表示される標準情報に加えて、オプションのアクセサリ ビュー (画像やラベルなど) をスクリーン キーボードに追加して、テキスト入力の目的を明確にしたり、ユーザーが必要な情報を入力するのを支援したりできます。
スクリーン キーボードの操作の詳細については、Apple の UIKeyboardType、キーボードの管理、データ入力のカスタム ビュー、iOS のテキスト プログラミング ガイドに関するドキュメントをご覧ください。
検索する
検索フィールドには、テキスト フィールドとスクリーン キーボードを提供する特殊な画面が表示され、ユーザーはキーボードの下に表示される項目のコレクションをフィルター処理できます。
ユーザーが検索フィールドに文字を入力すると、以下の結果に検索結果が自動的に反映されます。 ユーザーはいつでも結果にフォーカスを移動し、表示される項目のいずれかを選択できます。
Apple には、検索フィールドを操作するための次の推奨事項があります。
- 最近の検索を提供する - Siri Remote でのテキスト入力は面倒な場合があり、ユーザーは検索要求を繰り返す傾向があるため、キーボード領域の下の現在の結果の前に最近の検索結果のセクションを追加することをご検討ください。
- 可能な場合は、結果の数を制限する - ユーザーが大きな項目リストを解析および移動するのは困難な場合があるため、返される結果の数を制限することをご検討ください。
- 必要に応じて、検索結果フィルターを提供する - アプリによって提供されるコンテンツがそれ自体に適している場合は、返された検索結果をさらにフィルター処理できるようにスコープ バーを追加することをご検討ください。
詳細については、Apple の UISearchController クラス リファレンスに関する記事をご覧ください。
テキスト フィールドの操作
Xamarin.tvOS アプリでテキスト フィールドを操作する最も簡単な方法は、iOS デザイナーを使用してユーザー インターフェイス デザインに追加することです。
次の操作を行います。
コードでは、Text
プロパティを使用してテキスト フィールドの値を取得または設定できます。
Console.WriteLine ("User ID {0} and Password {1}", UserId.Text, Password.Text);
必要に応じて、Started
と Ended
テキスト フィールド イベントを使用して、テキスト入力の開始と終了に応答できます。
検索フィールドの操作
Xamarin.tvOS アプリで検索フィールドを操作する最も簡単な方法は、インターフェイス デザイナーを使用してユーザー インターフェイス デザインにフィールドを追加することです。
次の操作を行います。
Solution Pad で
Main.storyboard
ファイルをダブルクリックして、編集用に開きます。新しいコレクション ビュー コントローラーをストーリーボードにドラッグして、ユーザーの検索結果を表示します。
Properties Pad の [ウィジェット] タブで、[クラス]に
SearchResultsViewController
を使用し、[ストーリーボード ID] にSearchResults
を使用します。デザイン サーフェイスで [セル プロトタイプ] を選びます。
[プロパティ] エクスプローラーの [ウィジェット] タブで、[クラス] に
SearchResultCell
を使用し、[識別子] にImageCell
を使用します。[セル プロトタイプ] のデザインをレイアウトし、[プロパティ] エクスプローラーの [ウィジェット] タブで、各要素を一意の [名前] で公開します。
ストーリーボードへの変更を保存します。
データ モデルを指定する
次に、ユーザーが検索する結果のデータ モデルとして機能するクラスを提供する必要があります。 ソリューション エクスプローラーで [プロジェクト名] を右クリックし、[追加]>[新しいファイル...]>[全般]>[空のクラス] の順に選び、[名前] を指定します。
たとえば、ユーザーがタイトルとキーワードで画像のコレクションを検索できるようにするアプリは、次のようになります。
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
}
}
コレクション ビューのセル
データ モデルを配置したので、[プロトタイプ] セル (SearchResultViewCell.cs
) を編集し、次のように表示します。
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
}
}
この UpdateUI
メソッドは、プロパティが更新されるたびに、名前付き UI 要素の PictureInformation 項目 (PictureInfo
プロパティ) の個々のフィールドを表示するために使用されます。 たとえば、画像に関連付けられているイメージとタイトルです。
コレクション ビュー コントローラー
次に、検索結果コレクション ビュー コントローラー (SearchResultsViewController.cs
) を編集し、次のようにします。
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
}
}
まず、IUISearchResultsUpdating
ユーザーによって更新される検索コントローラー フィルターを処理するために、インターフェイスがクラスに追加されます。
public partial class SearchResultsViewController : UICollectionViewController , IUISearchResultsUpdating
定数は、コレクション コントローラーが新しいセルを要求するときに後で使用されるプロトタイプ セルの ID (上記のインターフェイス デザイナーで定義されている ID と一致する) を指定するためにも定義されます。
public const string CellID = "ImageCell";
ストレージは、検索対象のアイテムの完全な一覧、検索フィルター用語、およびその用語に一致する項目の一覧用に作成されます。
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 ();
}
}
SearchFilter
が変更されると、一致する項目の一覧が更新され、コレクション ビューのコンテンツが再読み込みされます。 この FindPictures
ルーチンは、新しい検索用語に一致する項目を検索する役割を担います。
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);
}
}
}
ユーザーが検索コントローラーのフィルターを変更すると、SearchFilter
の値が更新されます (結果コレクション ビューが更新されます)。
public void UpdateSearchResultsForSearchController (UISearchController searchController)
{
// Save the search filter and update the Collection View
SearchFilter = searchController.SearchBar.Text ?? string.Empty;
}
PopulatePictures
メソッドは、最初に使用可能な項目のコレクションを設定します。
private void PopulatePictures ()
{
// Clear list
AllPictures.Clear ();
// Add images
AllPictures.Add (new PictureInformation ("Antipasta Platter","Antipasta","cheese,grapes,tomato,coffee,meat,plate"));
...
}
この例では、コレクション ビュー コントローラーが読み込まれるときに、すべてのサンプル データがメモリ内に作成されます。 実際のアプリでは、このデータはおそらくデータベースまたは Web サービスから読み取られ、Apple TV の限られたメモリをオーバーランしないようにするために必要な場合に限られます。
NumberOfSections
と GetItemsCount
メソッドは、一致する項目の数を提供します。
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;
}
GetCell
メソッドは、コレクション ビューの各項目について、(ストーリーボードで上記で定義した CellID
に基づいて) 新しいプロトタイプ セルを返します。
public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath)
{
// Get a new cell and return it
var cell = collectionView.DequeueReusableCell (CellID, indexPath);
return (UICollectionViewCell)cell;
}
この WillDisplayCell
メソッドは、セルが表示される前に呼び出されるため、構成できます。
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;
}
DidUpdateFocus
メソッドは、結果コレクション ビューの項目を強調表示すると、ユーザーに視覚的なフィードバックを提供します。
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;
});
}
}
最後に、ItemSelected
メソッドは、結果コレクション ビューで項目を選択するユーザー操作 (Siri Remote で Touch サーフェスをクリックする) を処理します。
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);
}
検索フィールドがモーダル ダイアログ ビュー (呼び出し元のビューの上部) として表示された場合は、DismissViewController
メソッドを使用してユーザーがアイテムを選択したときに検索ビューを閉じます。 この例では、検索フィールドは [タブ ビュー] タブの内容として表示されるため、ここでは非表示になりません。
コレクション ビューの詳細については、コレクション ビューの操作に関するドキュメントをご覧ください。
検索フィールドの表示
検索フィールド (およびそれに関連付けられているスクリーン キーボードと検索結果) を tvOS でユーザーに表示するには、主に次の 2 つの方法があります。
- モーダル ダイアログ ビュー - 検索フィールドは、全画面表示のモーダル ダイアログ ビューとして、現在のビューとビュー コントローラーに表示できます。 これは通常、ユーザーによるボタンやその他の UI 要素のクリック操作の応答として行われます。 ユーザーが検索結果から項目を選択すると、ダイアログは閉じます。
- ビュー コンテンツ - 検索フィールドは、特定のビューの直接の部分です。 たとえば、タブ ビュー コントローラーの検索タブの内容などです。
上記の画像の検索可能なリストの例では、検索フィールドは [検索] タブの [コンテンツの表示] として表示され、[検索] タブ ビュー コントローラーは次のようになります。
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
}
}
最初に、インターフェイス デザイナーで検索結果コレクション ビュー コントローラーに割り当てられたストーリーボード識別子と一致する定数が定義されます。
public const string SearchResultsID = "SearchResults";
次に、このメソッドは ShowSearchController
新しい検索ビュー コレクション コントローラーを作成し、必要だった情報を表示します。
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);
}
上記のメソッドでは、ストーリーボードから SearchResultsViewController
がインスタンス化されると、検索フィールドとスクリーン キーボードをユーザーに表示する新しい UISearchController
メソッドが作成されます。 このキーボードの下に、(SearchResultsViewController
によって定義された) 検索結果コレクションが表示されます。
次に、SearchBar
がプレースホルダー ヒントなどの情報を使用して構成します。 これにより、実行される検索の種類に関する情報がユーザーに提供されます。
検索フィールドは、次の 2 つの方法のいずれかでユーザーに表示されます。
- モーダル ダイアログ ビュー -
PresentViewController
メソッドが呼び出され、既存のビューに対する検索が全画面表示で表示されます。 - ビュー コンテンツ - 検索コントローラーを含む
UISearchContainerViewController
が作成されます。 検索コンテナーを包含するためのUINavigationController
が作成され、ナビゲーション コントローラーがビュー コントローラーAddChildViewController (navController)
に追加され、ビューがView.Add (navController.View)
を表示します。
最後に、プレゼンテーションの種類に基づいて、ViewDidLoad
または ViewDidAppear
メソッドが ShowSearchController
メソッドを呼び出してユーザーに検索を表示します。
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 ();
}
アプリが実行され、ユーザーによって選択された [検索] タブでは、フィルター処理されていない項目の完全な一覧がユーザーに表示されます。
ユーザーが検索語句の入力を開始すると、結果の一覧がその用語によってフィルター処理され、自動的に更新されます。
ユーザーはいつでも、検索結果の項目にフォーカスを切り替え、Siri Remote の Touch サーフェスをクリックして選択できます。
まとめ
この記事では、Xamarin.tvOS アプリ内のテキスト フィールドと検索フィールドの設計方法と操作方法について説明しました。 インターフェイス デザイナーでテキストと検索コレクションの内容を作成する方法を示し、tvOS でユーザーに検索フィールドを表示する 2 つの異なる方法を示しました。