다음을 통해 공유


Xamarin에서 tvOS 텍스트 및 검색 필드 작업

필요한 경우 Xamarin.tvOS 앱은 텍스트 필드 및 화상 키보드를 사용하여 사용자(예: 사용자 ID 및 암호)로부터 작은 텍스트를 요청할 수 있습니다.

샘플 검색 필드

필요에 따라 검색 필드를 사용하여 앱 콘텐츠의 키워드(keyword) 검색 기능을 제공할 수 있습니다.

샘플 검색 결과

이 문서에서는 Xamarin.tvOS 앱에서 텍스트 및 검색 필드를 사용하는 자세한 내용을 다룹니다.

텍스트 및 검색 필드 정보

위에서 설명한 대로 필요한 경우 Xamarin.tvOS는 화면(또는 사용자가 설치한 tvOS 버전에 따라 선택적 bluetooth 키보드)을 사용하여 사용자로부터 소량의 텍스트를 수집하기 위해 하나 이상의 텍스트 필드를 표시할 수 있습니다.

또한 앱이 사용자에게 많은 양의 콘텐츠(예: 음악, 영화 또는 사진 컬렉션)를 제공하는 경우 사용자가 소량의 텍스트를 입력하여 사용 가능한 항목 목록을 필터링할 수 있는 검색 필드를 포함할 수 있습니다.

텍스트 필드

tvOS에서 텍스트 필드는 사용자가 클릭할 때 화면 키보드를 표시하는 고정 높이의 둥근 모서리 입력란으로 표시됩니다.

tvOS의 텍스트 필드

사용자가 포커스를 지정된 텍스트 필드로 이동하면 포커스가 커지고 깊은 그림자가 표시됩니다. 텍스트 필드가 포커스에 있을 때 다른 UI 요소와 겹칠 수 있으므로 사용자 인터페이스를 디자인할 때 이 점을 염두에 두어야 합니다.

Apple에는 텍스트 필드 작업에 대한 다음과 같은 제안이 있습니다.

  • 텍스트 항목 사용 - 화면 키보드의 특성상 긴 텍스트 섹션을 입력하거나 여러 텍스트 필드를 채우는 것은 사용자에게 지루합니다. 더 나은 해결 방법은 선택 목록 또는 단추를 사용하여 텍스트 항목의 양을 제한하는 것입니다.
  • 힌트를 사용하여 목적 전달 - 텍스트 필드가 비어 있는 경우 자리 표시자 "힌트"를 표시할 수 있습니다. 해당하는 경우 힌트를 사용하여 별도의 레이블 대신 텍스트 필드의 용도를 설명합니다.
  • 적절한 기본 키보드 유형을 선택합니다. tvOS는 텍스트 필드에 지정할 수 있는 여러 가지 용도로 작성된 키보드 유형을 제공합니다. 예를 들어 전자 메일 주소 키보드는 사용자가 최근에 입력한 주소 목록에서 선택할 수 있도록 하여 쉽게 입력할 수 있습니다.
  • 적절한 경우 보안 텍스트 필드를 사용합니다. 보안 텍스트 필드에는 실제 문자 대신 점으로 입력된 문자가 표시됩니다. 암호와 같은 중요한 정보를 수집할 때는 항상 보안 텍스트 필드를 사용합니다.

키보드

사용자가 사용자 인터페이스에서 텍스트 필드를 클릭할 때마다 선형 화상 키보드가 표시됩니다. 사용자는 Touch Surface The Siri Remote 를 사용하여 키보드에서 개별 문자를 선택하고 요청된 정보를 입력합니다.

Siri 원격 키보드

현재 보기 에 텍스트 필드가 두 개 이상 있는 경우 사용자를 다음 텍스트 필드로 이동하도록 다음 단추가 자동으로 표시됩니다. 텍스트 입력을 종료하고 사용자를 이전 화면으로 반환하는 마지막 텍스트 필드에 대해 완료 단추가 표시됩니다.

언제든지 사용자는 Siri 원격의 메뉴 단추를 눌러 텍스트 항목을 종료하고 다시 이전 화면으로 돌아갈 수 있습니다.

Apple에는 화상 키보드를 사용하기 위한 다음과 같은 제안이 있습니다.

  • 적절한 기본 키보드 유형을 선택합니다. tvOS는 텍스트 필드에 지정할 수 있는 여러 가지 용도로 작성된 키보드 유형을 제공합니다. 예를 들어 전자 메일 주소 키보드는 사용자가 최근에 입력한 주소 목록에서 선택할 수 있도록 하여 쉽게 입력할 수 있습니다.
  • 적절한 경우 키보드 액세서리 뷰 사용 - 항상 표시되는 표준 정보 외에도 선택적 액세서리 뷰(예: 이미지 또는 레이블)를 화상 키보드에 추가하여 텍스트 입력의 목적을 명확히 하거나 사용자가 필요한 정보를 입력할 수 있도록 지원할 수 있습니다.

화상 키보드 작업에 대한 자세한 내용은 Apple의 UIKeyboardType, 키보드 관리, 데이터 입력에 대한 사용자 지정 보기 및 iOS 설명서에 대한 텍스트 프로그래밍 가이드를 참조하세요.

검색 필드에는 사용자가 키보드 아래에 표시되는 항목 컬렉션을 필터링할 수 있는 텍스트 필드와 화상 키보드를 제공하는 특수한 화면이 표시됩니다.

샘플 검색 결과

사용자가 검색 필드에 문자를 입력하면 아래 결과가 검색 결과를 자동으로 반영합니다. 언제든지 사용자는 포커스를 결과로 이동하고 제공된 항목 중 하나를 선택할 수 있습니다.

Apple에는 검색 필드 작업에 대한 다음과 같은 제안이 있습니다.

  • 최근 검색 제공 - Siri 원격으로 텍스트를 입력하는 것은 지루할 수 있으며 사용자가 검색 요청을 반복하는 경향이 있으므로 키보드 영역 아래의 현재 결과 앞에 최근 검색 결과의 섹션을 추가하는 것이 좋습니다.
  • 가능하면 결과 수 제한 - 사용자가 구문 분석하고 탐색하기 어려울 수 있으므로 반환된 결과 수를 제한하는 것이 좋습니다.
  • 적절한 경우 검색 결과 필터 제공 - 앱에서 제공하는 콘텐츠가 자신에게 적합한 경우 사용자가 반환된 검색 결과를 추가로 필터링할 수 있도록 범위 표시줄을 추가하는 것이 좋습니다.

자세한 내용은 Apple의 UISearchController 클래스 참조를 참조하세요.

텍스트 필드 작업

Xamarin.tvOS 앱에서 텍스트 필드를 사용하는 가장 쉬운 방법은 iOS 디자이너를 사용하여 사용자 인터페이스 디자인에 추가하는 것입니다.

다음을 수행하십시오:

  1. Solution Pad에서 파일을 두 번 클릭하여 Main.storyboard 편집용으로 엽니다.

  2. 디자인 화면에서 하나 이상의 텍스트 필드를 보기로 끌어다 놓습니다.

    텍스트 필드

  3. 텍스트 필드를 선택하고 속성 패드위젯에서 각각 고유한 이름을 지정합니다.

    속성 패드의 위젯 탭

  4. 텍스트 필드 섹션에서 자리 표시자 힌트 및 기본값과 같은 요소를 정의할 수 있습니다.

    텍스트 필드 섹션

  5. 아래로 스크롤하여 맞춤법 검사, 대문자기본 키보드 유형과 같은 속성을 정의합니다.

    맞춤법 검사, 대문자 표시 및 기본 키보드 종류

  6. 변경 내용을 Storyboard에 저장합니다.

코드에서 해당 Text 속성을 사용하여 텍스트 필드의 값을 얻거나 설정할 수 있습니다.

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

필요에 따라 텍스트 필드 이벤트와 Ended 텍스트 필드 이벤트를 사용하여 Started 텍스트 항목 시작 및 종료에 응답할 수 있습니다.

검색 필드 작업

Xamarin.tvOS 앱에서 검색 필드를 사용하는 가장 쉬운 방법은 인터페이스 디자이너를 사용하여 사용자 인터페이스 디자인에 추가하는 것입니다.

다음을 수행하십시오:

  1. Solution Pad에서 파일을 두 번 클릭하여 Main.storyboard 편집용으로 엽니다.

  2. 새 컬렉션 뷰 컨트롤러를 Storyboard로 끌어 사용자의 검색 결과를 표시합니다.

    컬렉션 뷰 컨트롤러

  3. 속성 패드의 위젯 탭에서 클래스SearchResults 스토리보드 ID사용합니다 SearchResultsViewController.

    클래스 및 스토리보드 ID를 지정할 수 있는 Mac용 Visual Studio 위젯 탭입니다.

  4. 디자인 화면에서 셀 프로토타입을 선택합니다.

  5. 속성 탐색기의 위젯 탭에서 클래스ImageCell 식별자에 사용합니다 SearchResultCell.

    클래스 및 식별자를 지정할 수 있는 Mac용 Visual Studio 위젯 탭입니다.

  6. 셀 프로토타입의 디자인을 레이아웃하고 속성 탐색기의 위젯고유한 이름을 사용하여 각 요소를 노출합니다.

    셀 프로토타입 디자인 레이아웃

  7. 변경 내용을 Storyboard에 저장합니다.

데이터 모델 제공

다음으로, 사용자가 검색할 결과에 대한 데이터 모델 역할을 하는 클래스를 제공해야 합니다. 솔루션 탐색기 프로젝트 이름을 마우스 오른쪽 단추로 클릭하고 새 파일 추가>를 선택합니다.>일반>빈 클래스 및 이름 제공:

빈 클래스를 선택하고 이름을 입력합니다.

예를 들어 사용자가 제목 및 키워드로 사진 컬렉션을 검색할 수 있는 앱은 다음과 같을 수 있습니다.

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

이 예제에서는 컬렉션 뷰 컨트롤러가 로드될 때 모든 샘플 데이터가 메모리에 생성됩니다. 실제 앱에서 이 데이터는 데이터베이스 또는 웹 서비스에서 읽을 수 있으며 Apple TV의 제한된 메모리를 오버런하지 않도록 하는 데 필요한 경우에만 읽을 수 있습니다.

GetItemsCount 메서드는 NumberOfSections 일치하는 항목의 수를 제공합니다.

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 원격으로 터치 표면 클릭)를 처리합니다.

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에서 사용자에게 표시할 수 있는 두 가지 기본 방법이 있습니다.

  • 모달 대화 상자 보기 - 검색 필드는 현재 보기 및 보기 컨트롤러를 통해 전체 화면 모달 대화 상자 보기로 표시될 수 있습니다. 이 작업은 일반적으로 단추 또는 다른 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
    }
}

먼저 인터페이스 디자이너의 검색 결과 컬렉션 뷰 컨트롤러에 할당된 Storyboard 식별자와 일치하는 상수가 정의됩니다.

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

위의 메서드에서 Storyboard에서 인스턴스화되면 SearchResultsViewController 사용자에게 검색 필드 및 화상 키보드를 표시하는 새 UISearchController 항목이 만들어집니다. 검색 결과 컬렉션(정의된 SearchResultsViewController대로)이 이 키보드 아래에 표시됩니다.

다음으로 자리 SearchBar 표시자 힌트와 같은 정보로 구성됩니다 . 이렇게 하면 미리 형식이 지정된 검색 유형에 대한 정보가 사용자에게 제공됩니다.

그런 다음 검색 필드는 다음 두 가지 방법 중 하나로 사용자에게 표시됩니다.

  • 모달 대화 상자 보기 - PresentViewController 메서드가 호출되어 기존 보기 전체 화면에 대한 검색을 표시합니다.
  • 콘텐츠 보기 - 검색 컨트롤러를 포함하도록 A UISearchContainerViewController 가 만들어집니다. 검색 컨테이너를 포함하도록 A 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 원격의 터치 표면을 클릭하여 선택할 수 있습니다.

요약

이 문서에서는 Xamarin.tvOS 앱 내의 텍스트 및 검색 필드 디자인 및 작업에 대해 설명했습니다. 인터페이스 디자이너에서 텍스트 및 검색 컬렉션 콘텐츠를 만드는 방법을 보여 주었고 tvOS에서 사용자에게 검색 필드를 표시할 수 있는 두 가지 방법을 보여 줍니다.