Xamarin에서 tvOS 테이블 뷰 작업Working with tvOS Table Views in Xamarin

이 문서에서는 tvOS 앱 내에서 테이블 뷰 및 테이블 뷰 컨트롤러를 디자인 하 고 사용 하는 방법을 설명 합니다.This article covers designing and working with Table Views and Table View Controllers inside of a Xamarin.tvOS app.

TvOS에서는 테이블 뷰가 선택적으로 그룹 또는 섹션으로 구성 될 수 있는 스크롤 행의 단일 열로 표시 됩니다.In tvOS, a Table View is presented as a single column of scrolling rows that can optionally be organized into groups or sections. 테이블 뷰를 사용 하 여 많은 양의 데이터를 사용자에 게 효율적으로 표시 해야 하는 경우에는 명확 하 게 이해 해야 합니다.Table Views should be used when you need to display a large amount of data efficiently to the user, in a clear to understand way.

테이블 뷰는 일반적으로 분할 보기 의 한쪽에 탐색으로 표시 되 고, 선택한 항목의 세부 정보는 반대쪽에 표시 됩니다.Table Views are typically displayed in one side of a Split View as navigation, with the details of the selected item displayed in the opposite side:

테이블 뷰 정보About Table Views

UITableView은 스크롤할 수 있는 행의 단일 열을 선택적으로 그룹 또는 섹션으로 구성할 수 있는 정보 계층 목록으로 표시 합니다.A UITableView displays a single column of scrollable rows as a hierarchical list of information that can optionally be organized into groups or sections:

Apple에는 테이블 작업에 대 한 다음과 같은 제안이 있습니다.Apple has the following suggestions for working with tables:

  • 너비를 알고 있어야 합니다. 테이블 너비의 올바른 균형을 유지 하려고 합니다.Be Aware of Width - Try to strike the correct balance in your table widths. 테이블이 너무 넓은 경우 거리에서 검색 하기 어려울 수 있으며 사용 가능한 콘텐츠 영역에서 벗어날 수 있습니다.If the table is too wide, it can be difficult to scan from a distance and can take away from the available content area. 테이블이 너무 좁아서 정보를 자르거나 래핑할 수 있습니다 .이 경우 사용자가 대화방에서 읽기 어려울 수 있습니다.If the table is too narrow, it can cause the information to be truncated or wrap, again this can be difficult for the user to read from across the room.
  • 테이블 콘텐츠를 빠르게 표시 -데이터를 대량으로 표시 하 고, 콘텐츠를 지연 로드 하 고, 사용자에 게 테이블을 표시 하는 즉시 정보를 표시 하기 시작 합니다.Show Table Contents Quickly - For large lists of data, lazy-load the content and start showing information as soon as the table is presented to the user. 테이블을 로드 하는 데 시간이 오래 걸리는 경우에는 사용자가 앱에서 관심이 손실 되거나 잠긴 것으로 간주 될 수 있습니다.If the table takes to long to load, the user might lose interest in your app or think it is locked up.
  • 긴 콘텐츠 로드를 사용자 에 게 알립니다. 긴 테이블 로드 시간이 피할 수 없는 경우 앱이 잠기지 않았음을 알 수 있도록 진행률 표시줄이 나 작업 표시기 를 표시 합니다.Inform User of Long Content Loads - If a long table load time is unavoidable, present a Progress Bar or Activity Indicator so that they know the app hasn't locked up.

테이블 뷰 셀 형식Table View Cell Types

UITableViewCell은 테이블 뷰에서 데이터의 개별 행을 나타내는 데 사용 됩니다.A UITableViewCell is used to represent the individual Rows of data in the Table View. Apple은 몇 가지 기본 테이블 셀 형식을 정의 합니다.Apple has defined several default Table Cell Types:

  • 기본값 -이 형식은 셀 왼쪽에 옵션 이미지를 표시 하 고 오른쪽에 왼쪽 맞춤 제목을 표시 합니다.Default - This type presents an option Image on the left side of the Cell and left-aligned Title on the right.
  • 부제 -이 형식은 첫 번째 줄에 왼쪽 맞춤 제목을 표시 하 고 다음 줄에 더 작은 왼쪽에 맞춰진 부제목을 표시 합니다.Subtitle - This type presents a left-aligned Title on the first line and a smaller left-aligned Subtitle on the next line.
  • 값 1 -이 형식은 같은 줄에서 더 밝은 색, 오른쪽 맞춤 부제목이 있는 왼쪽 맞춤 제목을 표시 합니다.Value 1 - This type presents a left-aligned Title with a lighter colored, right-aligned Subtitle on the same line.
  • 값 2 -이 형식은 같은 줄에서 더 밝은 색으로 왼쪽에 맞춰진 부제목을 사용 하 여 오른쪽 맞춤 제목을 표시 합니다.Value 2 - This type presents a right-aligned Title with a lighter colored, left-aligned Subtitle on the same line.

모든 기본 테이블 뷰 셀 유형은 노출 표시기 또는 확인 표시와 같은 그래픽 요소도 지원 합니다.All of the default Table View Cell Types also support graphical elements such as Disclosure Indicators or Check Marks.

또한 사용자 지정 테이블 뷰 셀 형식을 정의 하 고 사용자가 인터페이스 디자이너 또는 코드를 통해 만든 _프로토타입 셀_을 표시할 수 있습니다.Additionally, you can define a Custom Table View Cell Type and present a Prototype Cell, that you either create in the Interface Designer or via code.

Apple에는 테이블 뷰 셀을 사용 하기 위한 다음과 같은 제안이 있습니다.Apple has the following suggestions for working with Table View Cells:

  • 텍스트 클리핑 방지 -잘림 방지 되도록 개별 텍스트 줄을 짧게 유지 합니다.Avoid Text Clipping - Keep the individual lines of text short so that they don't end up truncated. 잘린 단어나 구는 대화방에서 구문을 분석 하는 데 사용 하기 어렵습니다.Truncated words or phrases are hard for the user to parse from across the room.
  • 포커스가 있는 행 상태를 고려 합니다. 포커스가 있으면 모든 상태에서 셀의 모양을 테스트 해야 합니다.Consider the Focused Row State - Because a Row becomes bigger, with more rounded corners when in focus, you need to test your Cell's appearance in all states. 포커스가 있는 상태에서 이미지나 텍스트가 잘리거나 잘못 표시 될 수 있습니다.Images or text may become clipped or look incorrect in the Focused state.
  • 편집 가능한 테이블 사용 -테이블 행 이동 또는 삭제는 IOS 보다 tvOS에서 더 많은 시간이 걸립니다.Use Editable Tables Sparingly - Moving or deleting Table Rows is more time consuming on tvOS than iOS. 이 기능이 tvOS 앱을 추가 하거나 방해 여부를 신중 하 게 결정 해야 합니다.You need to decide carefully if this feature will add or distract from your tvOS app.
  • 적절 한 경우 사용자 지정 셀 유형을 만듭니다 . 기본 제공 테이블 뷰 셀 유형은 여러 상황에서 매우 유용 하지만, 비표준 정보에 대 한 사용자 지정 셀 유형을 만들어 더 많은 제어를 제공 하 고 정보를에 더 효과적으로 제공 하는 것이 좋습니다. 정의.Create Custom Cell Types Where Appropriate - While the built-in Table View Cell Types are great for many situations, consider creating Custom Cell Types for non-standard information to provide greater control and better present the information to the user.

테이블 뷰 작업Working With Table Views

TvOS 앱에서 테이블 뷰로 작업 하는 가장 쉬운 방법은 인터페이스 디자이너에서 모양을 만들고 수정 하는 것입니다.The easiest way to work with Table Views in a Xamarin.tvOS app is to create and modify their appearance in the Interface Designer.

시작하려면 다음을 수행합니다.To get started, do the following:

  1. Mac용 Visual Studio에서 새 tvOS app 프로젝트를 시작 하 고 tvOS > App > 단일 뷰 앱 을 선택 하 고 다음 단추를 클릭 합니다.In Visual Studio for Mac, start a new tvOS app project and select tvOS > App > Single View App and click the Next button:

  2. 앱의 이름을 입력 하 고 다음을 클릭 합니다.Enter a Name for the app and click Next:

  3. 프로젝트 이름솔루션 이름을 조정 하거나 기본값을 적용 하 고 만들기 단추를 클릭 하 여 새 솔루션을 만듭니다.Either adjust the Project Name and Solution Name or accept the defaults and click the Create button to create the new solution:

  4. Solution Pad에서 Main.storyboard 파일을 두 번 클릭 하 여 iOS 디자이너에서 엽니다.In the Solution Pad, double-click the Main.storyboard file to open it in the iOS Designer:

  5. 기본 뷰 컨트롤러를 선택 하 고 삭제 합니다.Select and delete the Default View Controller:

  6. 도구 상자 에서 분할 뷰 컨트롤러 를 선택 하 고 Design Surface 끌어 옵니다.Select a Split View Controller from the Toolbox and drag it onto the Design Surface.

  7. 기본적으로 왼쪽에는 탐색 뷰 컨트롤러 와 뷰 컨트롤러, 오른쪽에는 뷰 컨트롤러 를 사용 하 여 분할 뷰가 표시 됩니다.By default, you'll get a Split View with a Navigation View Controller and a Table View Controller in the left hand side and a View Controller in the right hand side. 다음은 tvOS에서 테이블 뷰에 대 한 Apple의 제안 된 사용법입니다.This is Apple's suggested usage of a Table View in tvOS:

  8. C# 나중에 코드에서 액세스할 수 있도록 테이블 뷰의 모든 부분을 선택 하 고 속성 탐색기위젯 탭에서 사용자 지정 클래스 이름을 할당 해야 합니다.You will need to select every part of the Table View and assign it a custom Class Name in the Widget tab of the Properties Explorer so that you can access it later in C# code. 예를 들어 테이블 뷰 컨트롤러는 다음과 같습니다.For example, the Table View Controller:

  9. 테이블 뷰 컨트롤러, 테이블 뷰프로토타입 셀에 대 한 사용자 지정 클래스를 만들어야 합니다.Ensure that you create a custom class for the Table View Controller, the Table View and any Prototype Cells. Mac용 Visual Studio는 사용자 지정 클래스를 만들 때 프로젝트 트리에 추가 합니다.Visual Studio for Mac will add the custom classes to the Project Tree as they are created:

  10. 그런 다음 Design Surface에서 테이블 뷰를 선택 하 고 필요에 따라 속성을 조정 합니다.Next, select the Table View in the Design Surface and adjust it's properties as needed. 예: 프로토타입 셀 수 및 스타일 (일반 또는 그룹화 됨):Such as the number of Prototype Cells and the Style (Plain or Grouped):

  11. 프로토타입 셀에 대해 해당 셀을 선택 하 고 속성 탐색기위젯 탭에서 고유한 식별자 를 할당 합니다.For each Prototype Cell, select it and assign a unique Identifier in the Widget tab of the Properties Explorer. 이 단계는 나중에 테이블을 채울 때이 식별자가 필요 하므로 매우 중요 합니다.This step is very important as you will need this Identifier later when you populate the table. AttrCell:For example AttrCell:

  12. 또한 스타일 드롭다운을 통해 기본 테이블 뷰 셀 형식 으로 셀을 표시 하거나 사용자 지정 으로 설정 하 고 Design Surface를 사용 하 여 도구 상자에서 다른 UI 위젯에서 끌어 셀을 레이아웃 하도록 선택할 수 있습니다.You can also select to present the Cell as one of the Default Table View Cell Types via the Style dropdown or set it to Custom and use the Design Surface to layout the Cell by dragging in other UI widgets from the Toolbox:

  13. 속성 탐색기 의 C# 위젯 탭에서 프로토타입 셀 디자인의 각 UI 요소에 고유한 이름을 할당 하 여 나중에 코드에서 액세스할 수 있도록 합니다.Assign a unique Name to each UI element in the Prototype Cell design in the Widget tab of the Properties Explorer so you can access them later in C# code:

  14. 테이블 뷰의 모든 프로토타입 셀에 대해 위의 단계를 반복 합니다.Repeat the above step for all of the Prototype Cells in the Table View.

  15. 그런 다음 UI 디자인의 나머지 부분에 사용자 지정 클래스를 할당 하 고 자세히 보기를 레이아웃 한 다음에서 C# 액세스할 수 있도록 세부 정보 보기의 각 Ui 요소에 고유한 이름을 할당 합니다.Next, assign custom classes to the rest of your UI design, layout the Details view and assign unique Names to each UI element in the Details view so that you can access them in C# as well. 예를 들면 다음과 같습니다.For Example:

  16. 스토리 보드에 변경 내용을 저장 합니다.Save your Changes to the Storyboard.

데이터 모델 디자인Designing a Data Model

사용자가 테이블 뷰에서 행을 선택 하거나 강조 표시 함에 따라 테이블 보기가 더 쉽게 표시 하 고 자세한 정보를 쉽게 표시 하기 위해 정보를 사용 하 여 작업을 수행 하려면 사용자 지정 클래스를 만들어 표시 되는 정보에 대 한 데이터 모델 역할을 수행 합니다. .To make working with the information that the Table View will display easier and to ease presenting of detailed information (as the user selects or highlights Rows in the Table View), create a custom class or classes to act as the Data Model for the information presented.

각각 사용자가 선택할 수 있는 고유한 맛보기 목록을 포함 하는 도시목록이 포함 된 여행 예약 앱의 예를 사용 합니다.Take the example of a travel booking app that contains a list of Cities, each that contains a unique list of Attractions that the user can select. 사용자는 인력를 즐겨찾기로표시할 수 있습니다. 인력에 대 한 지침 을 얻고 지정 된 도시에 비행 을 이동 하도록 선택 합니다.The user will be able to mark an attraction as a Favorite, select to get Directions to an attraction and Book a Flight to a given city.

인력에 대 한 데이터 모델을 만들려면 Solution Pad 에서 프로젝트 이름을 마우스 오른쪽 단추로 클릭 하 고 추가 > 새 파일...을 선택 합니다. 이름AttractionInformation를 입력 하 고 새로 만들기 단추를 클릭 합니다.To create the Data Model for an Attraction, right-click on the Project Name in the Solution Pad and select Add > New File.... Enter AttractionInformation for the Name and click the New button:

AttractionInformation.cs 파일을 편집 하 여 다음과 같이 만듭니다.Edit the AttractionInformation.cs file and make it look like the following:

using System;
using Foundation;

namespace tvTable
{
    public class AttractionInformation : NSObject
    {
        #region Computed Properties
        public CityInformation City { get; set;}
        public string Name { get; set;}
        public string Description { get; set;}
        public string ImageName { get; set;}
        public bool IsFavorite { get; set;}
        public bool AddDirections { get; set;}
        #endregion

        #region Constructors
        public AttractionInformation (string name, string description, string imageName)
        {
            // Initialize
            this.Name = name;
            this.Description = description;
            this.ImageName = imageName;
        }
        #endregion
    }
}

이 클래스는 지정 된 인력에 대 한 정보를 저장 하는 속성을 제공 합니다.This class provides the properties to store the information about a given Attraction.

그런 다음 Solution Pad 에서 프로젝트 이름을 다시 마우스 오른쪽 단추로 클릭 하 고 추가 > 새 파일...을 선택 합니다. 이름CityInformation를 입력 하 고 새로 만들기 단추를 클릭 합니다.Next, right-click on the Project Name in the Solution Pad again and select Add > New File.... Enter CityInformation for the Name and click the New button:

CityInformation.cs 파일을 편집 하 여 다음과 같이 만듭니다.Edit the CityInformation.cs file and make it look like the following:

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

namespace tvTable
{
    public class CityInformation : NSObject
    {
        #region Computed Properties
        public string Name { get; set; }
        public List<AttractionInformation> Attractions { get; set;}
        public bool FlightBooked { get; set;}
        #endregion

        #region Constructors
        public CityInformation (string name)
        {
            // Initialize
            this.Name = name;
            this.Attractions = new List<AttractionInformation> ();
        }
        #endregion

        #region Public Methods
        public void AddAttraction (AttractionInformation attraction)
        {
            // Mark as belonging to this city
            attraction.City = this;

            // Add to collection
            Attractions.Add (attraction);
        }

        public void AddAttraction (string name, string description, string imageName)
        {
            // Create attraction
            var attraction = new AttractionInformation (name, description, imageName);

            // Mark as belonging to this city
            attraction.City = this;

            // Add to collection
            Attractions.Add (attraction);
        }
        #endregion
    }
}

이 클래스는 해당 도시의 맛보기 컬렉션인 대상 도시에 대 한 모든 정보를 포함 하며, 도시에 맛보기를 더 쉽게 추가할 수 있도록 두 개의 도우미 메서드 (AddAttraction)를 제공 합니다.This class holds all of the information about a destination City, a collection of Attractions for that city and provides two helper methods (AddAttraction) to make it easier to add attractions to the city.

테이블 뷰 데이터 원본The Table View Data Source

각 테이블 뷰에서는 테이블에 대 한 데이터를 제공 하 고 테이블 뷰에 필요한 행을 생성 하기 위해 데이터 원본 (UITableViewDataSource)이 필요 합니다.Each Table View requires a Data Source (UITableViewDataSource) to provide the data for the Table and generate the necessary Rows as required by the Table View.

위의 예에서는 솔루션 탐색기의 프로젝트 이름을 마우스 오른쪽 단추로 클릭 하 고 새 파일 > 추가 ...를 선택한 다음 AttractionTableDatasource를 호출 하 고 새로 만들기 단추를 클릭 하 여 만듭니다.For the example given above, right-click on the Project Name in the Solution Explorer, select Add > New File... and call it AttractionTableDatasource and click the New button to create. 그런 다음 AttractionTableDatasource.cs 파일을 편집 하 여 다음과 같이 만듭니다.Next, edit the AttractionTableDatasource.cs file and make it look like the following:

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

namespace tvTable
{
    public class AttractionTableDatasource : UITableViewDataSource
    {
        #region Constants
        const string CellID = "AttrCell";
        #endregion

        #region Computed Properties
        public AttractionTableViewController Controller { get; set;}
        public List<CityInformation> Cities { get; set;}
        #endregion

        #region Constructors
        public AttractionTableDatasource (AttractionTableViewController controller)
        {
            // Initialize
            this.Controller = controller;
            this.Cities = new List<CityInformation> ();
            PopulateCities ();
        }
        #endregion

        #region Public Methods
        public void PopulateCities ()
        {
            // Clear existing
            Cities.Clear ();

            // Define cities and attractions
            var Paris = new CityInformation ("Paris");
            Paris.AddAttraction ("Eiffel Tower", "Is a wrought iron lattice tower on the Champ de Mars in Paris, France.", "EiffelTower");
            Paris.AddAttraction ("Musée du Louvre", "is one of the world's largest museums and a historic monument in Paris, France.", "Louvre");
            Paris.AddAttraction ("Moulin Rouge", "French for 'Red Mill', is a cabaret in Paris, France.", "MoulinRouge");
            Paris.AddAttraction ("La Seine", "Is a 777-kilometre long river and an important commercial waterway within the Paris Basin.", "RiverSeine");
            Cities.Add (Paris);

            var SanFran = new CityInformation ("San Francisco");
            SanFran.AddAttraction ("Alcatraz Island", "Is located in the San Francisco Bay, 1.25 miles (2.01 km) offshore from San Francisco.", "Alcatraz");
            SanFran.AddAttraction ("Golden Gate Bridge", "Is a suspension bridge spanning the Golden Gate strait between San Francisco Bay and the Pacific Ocean", "GoldenGateBridge");
            SanFran.AddAttraction ("San Francisco", "Is the cultural, commercial, and financial center of Northern California.", "SanFrancisco");
            SanFran.AddAttraction ("Telegraph Hill", "Is primarily a residential area, much quieter than adjoining North Beach.", "TelegraphHill");
            Cities.Add (SanFran);

            var Houston = new CityInformation ("Houston");
            Houston.AddAttraction ("City Hall", "It was constructed in 1938-1939, and is located in Downtown Houston.", "CityHall");
            Houston.AddAttraction ("Houston", "Is the most populous city in Texas and the fourth most populous city in the US.", "Houston");
            Houston.AddAttraction ("Texas Longhorn", "Is a breed of cattle known for its characteristic horns, which can extend to over 6 ft.", "LonghornCattle");
            Houston.AddAttraction ("Saturn V Rocket", "was an American human-rated expendable rocket used by NASA between 1966 and 1973.", "Rocket");
            Cities.Add (Houston);
        }
        #endregion

        #region Override Methods
        public override UITableViewCell GetCell (UITableView tableView, Foundation.NSIndexPath indexPath)
        {
            // Get cell
            var cell = tableView.DequeueReusableCell (CellID) as AttractionTableCell;

            // Populate cell
            cell.Attraction = Cities [indexPath.Section].Attractions [indexPath.Row];

            // Return new cell
            return cell;
        }

        public override nint NumberOfSections (UITableView tableView)
        {
            // Return number of cities
            return Cities.Count;
        }

        public override nint RowsInSection (UITableView tableView, nint section)
        {
            // Return the number of attractions in the given city
            return Cities [(int)section].Attractions.Count;
        }

        public override string TitleForHeader (UITableView tableView, nint section)
        {
            // Get the name of the current city
            return Cities [(int)section].Name;
        }
        #endregion
    }
}

클래스의 몇 가지 섹션을 자세히 살펴보겠습니다.Let's take a look at a few sections of the class in detail.

먼저 프로토타입 셀의 고유 식별자 (위의 인터페이스 디자이너에서 할당 된 식별자)를 포함 하는 상수를 정의 하 고 테이블 뷰 컨트롤러에 바로 가기를 추가 하 고 데이터에 대 한 저장소를 만들었습니다.First, we have defined a constant to hold the unique Identifier of the Prototype Cell (this is the same Identifier assigned in the Interface Designer above), added a shortcut back to the Table View Controller and created storage for our data:

const string CellID = "AttrCell";
public AttractionTableViewController Controller { get; set;}
public List<CityInformation> Cities { get; set;}

다음으로, 클래스를 만들 때 테이블 뷰 컨트롤러를 저장 한 다음 위에 정의 된 데이터 모델을 사용 하 여 데이터 소스를 작성 하 고 채웁니다.Next, we save the Table View Controller, then build and populate our data source (using the Data Models defined above) when the class is created:

public AttractionTableDatasource (AttractionTableViewController controller)
{
    // Initialize
    this.Controller = controller;
    this.Cities = new List<CityInformation> ();
    PopulateCities ();
}

예를 들어, PopulateCities 메서드는 단순히 메모리에 데이터 모델 개체를 만들지만 실제 응용 프로그램의 데이터베이스 또는 웹 서비스에서 쉽게 읽을 수 있습니다.For the sake of example, the PopulateCities method simply creates Data Model objects in memory however these could easily be read from a database or web service in a real app:

public void PopulateCities ()
{
    // Clear existing
    Cities.Clear ();

    // Define cities and attractions
    var Paris = new CityInformation ("Paris");
    Paris.AddAttraction ("Eiffel Tower", "Is a wrought iron lattice tower on the Champ de Mars in Paris, France.", "EiffelTower");
    ...
}

NumberOfSections 메서드는 테이블에 있는 섹션의 수를 반환 합니다.The NumberOfSections method returns the number of Sections in the table:

public override nint NumberOfSections (UITableView tableView)
{
    // Return number of cities
    return Cities.Count;
}

일반 스타일의 테이블 뷰에서는 항상 1을 반환 합니다.For Plain styled Table Views, always return 1.

RowsInSection 메서드는 현재 섹션의 행 수를 반환 합니다.The RowsInSection method returns the number of Rows in the current Section:

public override nint RowsInSection (UITableView tableView, nint section)
{
    // Return the number of attractions in the given city
    return Cities [(int)section].Attractions.Count;
}

다시, 일반 테이블 보기의 경우 데이터 원본에 있는 총 항목 수를 반환 합니다.Again, for Plain Table Views, return the total number of items in the data source.

TitleForHeader 메서드는 지정 된 섹션에 대 한 제목을 반환 합니다.The TitleForHeader method returns the Title for given Section:

public override string TitleForHeader (UITableView tableView, nint section)
{
    // Get the name of the current city
    return Cities [(int)section].Name;
}

일반 테이블 뷰 형식의 경우 제목을 비워 둡니다 ("").For a Plain Table View type, leave the title blank ("").

마지막으로 테이블 뷰에서 요청 될 때 GetCell 메서드를 사용 하 여 프로토타입 셀을 만들고 채웁니다.Finally, when requested by the Table View, create and populate a Prototype Cell using the GetCell method:

public override UITableViewCell GetCell (UITableView tableView, Foundation.NSIndexPath indexPath)
{
    // Get cell
    var cell = tableView.DequeueReusableCell (CellID) as AttractionTableCell;

    // Populate cell
    cell.Attraction = Cities [indexPath.Section].Attractions [indexPath.Row];

    // Return new cell
    return cell;
}

UITableViewDatasource작업에 대 한 자세한 내용은 Apple의 Uitableviewdatasource 설명서를 참조 하세요.For more information on working with a UITableViewDatasource, please see Apple's UITableViewDatasource documentation.

테이블 뷰 대리자The Table View Delegate

각 테이블 뷰에는 테이블의 사용자 상호 작용 또는 다른 시스템 이벤트에 응답 하는 대리자 (UITableViewDelegate)가 필요 합니다.Each Table View requires a Delegate (UITableViewDelegate) to respond to user interaction or other system events on the Table.

위의 예에서는 솔루션 탐색기의 프로젝트 이름을 마우스 오른쪽 단추로 클릭 하 고 새 파일 > 추가 ...를 선택한 다음 AttractionTableDelegate를 호출 하 고 새로 만들기 단추를 클릭 하 여 만듭니다.For the example given above, right-click on the Project Name in the Solution Explorer, select Add > New File... and call it AttractionTableDelegate and click the New button to create. 그런 다음 AttractionTableDelegate.cs 파일을 편집 하 여 다음과 같이 만듭니다.Next, edit the AttractionTableDelegate.cs file and make it look like the following:

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

namespace tvTable
{
    public class AttractionTableDelegate : UITableViewDelegate
    {
        #region Computed Properties
        public AttractionTableViewController Controller { get; set;}
        #endregion

        #region Constructors
        public AttractionTableDelegate (AttractionTableViewController controller)
        {
            // Initializw
            this.Controller = controller;
        }
        #endregion

        #region Override Methods
        public override void RowSelected (UITableView tableView, Foundation.NSIndexPath indexPath)
        {
            var attraction = Controller.Datasource.Cities [indexPath.Section].Attractions [indexPath.Row];
            attraction.IsFavorite = (!attraction.IsFavorite);

            // Update UI
            Controller.TableView.ReloadData ();
        }

        public override bool CanFocusRow (UITableView tableView, Foundation.NSIndexPath indexPath)
        {
            // Inform caller of highlight change
            RaiseAttractionHighlighted (Controller.Datasource.Cities [indexPath.Section].Attractions [indexPath.Row]);
            return true;
        }
        #endregion

        #region Events
        public delegate void AttractionHighlightedDelegate (AttractionInformation attraction);
        public event AttractionHighlightedDelegate AttractionHighlighted;

        internal void RaiseAttractionHighlighted (AttractionInformation attraction)
        {
            // Inform caller
            if (this.AttractionHighlighted != null) this.AttractionHighlighted (attraction);
        }
        #endregion
    }
}

이 클래스의 몇 가지 섹션을 자세히 살펴보겠습니다.Let's take a look at several sections of this class in details.

먼저 클래스를 만들 때 테이블 뷰 컨트롤러에 대 한 바로 가기를 만듭니다.First, we create a shortcut to the Table View Controller when the class is created:

public AttractionTableViewController Controller { get; set;}
...

public AttractionTableDelegate (AttractionTableViewController controller)
{
    // Initialize
    this.Controller = controller;
}

그런 다음, 행이 선택 되 면 (사용자가 Apple 원격의 터치 화면을 클릭 하면) 선택한 행으로 표시 되는 인력 을 즐겨찾기로 표시 하려고 합니다.Then, when a row is selected (the user clicks on the Touch Surface of the Apple Remote) we want to mark the Attraction represented by the selected Row as a Favorite:

public override void RowSelected (UITableView tableView, Foundation.NSIndexPath indexPath)
{
    var attraction = Controller.Datasource.Cities [indexPath.Section].Attractions [indexPath.Row];
    attraction.IsFavorite = (!attraction.IsFavorite);

    // Update UI
    Controller.TableView.ReloadData ();
}

그런 다음 사용자가 행을 강조 표시할 때 (Apple 원격 터치 화면을 사용 하 여 포커스를 제공) 분할 보기 컨트롤러의 세부 정보 섹션에 해당 행으로 표시 되는 인력 의 세부 정보를 표시 하려고 합니다.Next, when the user highlights a Row (by giving it Focus using the Apple Remote Touch Surface) we want to present the Details of the Attraction represented by that Row in the Details section of our Split View Controller:

public override bool CanFocusRow (UITableView tableView, Foundation.NSIndexPath indexPath)
{
    // Inform caller of highlight change
    RaiseAttractionHighlighted (Controller.Datasource.Cities [indexPath.Section].Attractions [indexPath.Row]);
    return true;
}
...

public delegate void AttractionHighlightedDelegate (AttractionInformation attraction);
public event AttractionHighlightedDelegate AttractionHighlighted;

internal void RaiseAttractionHighlighted (AttractionInformation attraction)
{
    // Inform caller
    if (this.AttractionHighlighted != null) this.AttractionHighlighted (attraction);
}

테이블 뷰에서 포커스를 가져올 각 행에 대해 CanFocusRow 메서드가 호출 됩니다.The CanFocusRow method is called for each Row that is about to get Focus in the Table View. 행이 포커스를 받을 수 있으면 true을 반환 하 고, 그렇지 않으면 false을 반환 합니다.Return true if the Row can get Focus, else return false. 이 예제의 경우 포커스를 받을 때 각 행에 대해 발생 하는 사용자 지정 AttractionHighlighted 이벤트를 만들었습니다.In the case of this example, we have created a custom AttractionHighlighted event that will be raised on each Row as it receives Focus.

UITableViewDelegate작업에 대 한 자세한 내용은 Apple의 Uitableviewdelegate 설명서를 참조 하세요.For more information on working with a UITableViewDelegate, please see Apple's UITableViewDelegate documentation.

테이블 뷰 셀The Table View Cell

인터페이스 디자이너에서 테이블 뷰에 추가한 각 프로토타입 셀에 대해 테이블 뷰 셀 (UITableViewCell)의 사용자 지정 인스턴스를 만들어 새 셀 (행)을 만들 때 채울 수 있습니다.For each Prototype Cell that you added to the Table View in the Interface Designer, you also created a custom instance of the Table View Cell (UITableViewCell) to allow you to populate the new cell (Row) as it is created.

예제 앱의 경우 AttractionTableCell.cs 파일을 두 번 클릭 하 여 편집용으로 열고 다음과 같이 표시 합니다.For the example app, double-click the AttractionTableCell.cs file to open it for editing and make it look like the following:

using System;
using Foundation;
using UIKit;

namespace tvTable
{
    public partial class AttractionTableCell : UITableViewCell
    {
        #region Private Variables
        private AttractionInformation _attraction = null;
        #endregion

        #region Computed Properties
        public AttractionInformation Attraction {
            get { return _attraction; }
            set {
                _attraction = value;
                UpdateUI ();
            }
        }
        #endregion

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

        #region Private Methods
        private void UpdateUI ()
        {
            // Trap all errors
            try {
                Title.Text = Attraction.Name;
                Favorite.Hidden = (!Attraction.IsFavorite);
            } catch {
                // Since the UI might not be fully loaded, ignore
                // all errors at this point
            }
        }
        #endregion
    }
}

이 클래스는 지정 된 행에 표시 되는 인력 데이터 모델 개체 (위에 정의 된AttractionInformation)에 대 한 저장소를 제공 합니다.This class provides storage for the Attraction Data Model object (AttractionInformation as defined above) displayed in the given Row:

private AttractionInformation _attraction = null;
...

public AttractionInformation Attraction {
    get { return _attraction; }
    set {
        _attraction = value;
        UpdateUI ();
    }
}

UpdateUI 메서드는 필요에 따라 인터페이스 디자이너에서 셀의 프로토타입에 추가 된 UI 위젯을 채웁니다.The UpdateUI method populates the UI Widgets (that were added to the Cell's prototype in the Interface Designer) as required:

private void UpdateUI ()
{
    // Trap all errors
    try {
        Title.Text = Attraction.Name;
        Favorite.Hidden = (!Attraction.IsFavorite);
    } catch {
        // Since the UI might not be fully loaded, ignore
        // all errors at this point
    }
}

UITableViewCell작업에 대 한 자세한 내용은 Apple의 Uitableviewcell 설명서를 참조 하세요.For more information on working with a UITableViewCell, please see Apple's UITableViewCell documentation.

테이블 뷰 컨트롤러The Table View Controller

UITableViewController(테이블 뷰 컨트롤러)는 인터페이스 디자이너를 통해 스토리 보드에 추가 된 테이블 뷰를 관리 합니다.A Table View Controller (UITableViewController) manages a Table View that has been added to a Storyboard via the Interface Designer.

예제 앱의 경우 AttractionTableViewController.cs 파일을 두 번 클릭 하 여 편집용으로 열고 다음과 같이 표시 합니다.For the example app, double-click the AttractionTableViewController.cs file to open it for editing and make it look like the following:

using System;
using Foundation;
using UIKit;

namespace tvTable
{
    public partial class AttractionTableViewController : UITableViewController
    {
        #region Computed Properties
        public AttractionTableDatasource Datasource {
            get { return TableView.DataSource as AttractionTableDatasource; }
        }

        public AttractionTableDelegate TableDelegate {
            get { return TableView.Delegate as AttractionTableDelegate; }
        }
        #endregion

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

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

            // Setup table
            TableView.DataSource = new AttractionTableDatasource (this);
            TableView.Delegate = new AttractionTableDelegate (this);
            TableView.ReloadData ();
        }
        #endregion
    }
}

이 클래스를 좀 더 자세히 살펴보겠습니다.Let's take a closer look at this class. 먼저 테이블 뷰의 DataSourceTableDelegate에 보다 쉽게 액세스할 수 있도록 하는 바로 가기를 만들었습니다.First, we have created shortcuts to make it easier to access the Table View's DataSource and TableDelegate. 나중에이를 사용 하 여 분할 뷰의 왼쪽에 있는 테이블 뷰와 오른쪽의 자세히 보기 사이에 통신 합니다.We'll use those later to communicate between the Table View in the left side of the Split View and the Details View in the right.

마지막으로 테이블 뷰가 메모리에 로드 되 면 AttractionTableDatasource 인스턴스를 만들고 (위에서 만든 AttractionTableDelegate) 테이블 뷰에 연결 합니다.Finally, when the Table View is loaded into memory, we create instances of the AttractionTableDatasource and AttractionTableDelegate (both created above) and attach them to the Table View.

UITableViewController작업에 대 한 자세한 내용은 Apple의 Uitableviewcontroller 설명서를 참조 하세요.For more information on working with a UITableViewController, please see Apple's UITableViewController documentation.

모두 함께 끌어오기Pulling it All Together

이 문서의 시작 부분에서 설명한 것 처럼 테이블 뷰는 일반적으로 분할 보기 의 한쪽에 탐색으로 표시 되 고 반대쪽에는 선택한 항목의 세부 정보가 표시 됩니다.As stated at the start of this document, Table Views are typically displayed in one side of a Split View as navigation, with the details of the selected item displayed in the opposite side. 예를 들면,For example:

이 패턴은 tvOS의 표준 패턴 이므로 모든 항목을 함께 가져오고 분할 보기의 왼쪽과 오른쪽이 서로 상호 작용 하는 마지막 단계를 살펴보겠습니다.Since this is a standard pattern in tvOS, let's look at the final steps to bring everything together and have the left and right sides of the Split View interact with each other.

자세히 보기The Detail View

위에서 언급 한 여행 앱의 예제에서는 사용자 지정 클래스 (AttractionViewController)가 분할 뷰의 오른쪽에 표시 되는 표준 뷰 컨트롤러에 대해 자세히 보기로 정의 됩니다.For the example of the travel app presented above, a custom class (AttractionViewController) is defined for the standard View Controller presented in the right side of the Split View as the Detail View:

using System;
using Foundation;
using UIKit;

namespace tvTable
{
    public partial class AttractionViewController : UIViewController
    {
        #region Private Variables
        private AttractionInformation _attraction = null;
        #endregion

        #region Computed Properties
        public AttractionInformation Attraction {
            get { return _attraction; }
            set {
                _attraction = value;
                UpdateUI ();
            }
        }

        public MasterSplitView SplitView { get; set;}
        #endregion

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

        #region Public Methods
        public void UpdateUI ()
        {
            // Trap all errors
            try {
                City.Text = Attraction.City.Name;
                Title.Text = Attraction.Name;
                SubTitle.Text = Attraction.Description;

                IsFlighBooked.Hidden = (!Attraction.City.FlightBooked);
                IsFavorite.Hidden = (!Attraction.IsFavorite);
                IsDirections.Hidden = (!Attraction.AddDirections);
                BackgroundImage.Image = UIImage.FromBundle (Attraction.ImageName);
                AttractionImage.Image = BackgroundImage.Image;
            } catch {
                // Since the UI might not be fully loaded, ignore
                // all errors at this point
            }
        }
        #endregion

        #region Override Methods
        public override void ViewWillAppear (bool animated)
        {
            base.ViewWillAppear (animated);

            // Ensure the UI Updates
            UpdateUI ();
        }
        #endregion

        #region Actions
        partial void BookFlight (NSObject sender)
        {
            // Ask user to book flight
            AlertViewController.PresentOKCancelAlert ("Book Flight",
                                                      string.Format ("Would you like to book a flight to {0}?", Attraction.City.Name),
                                                      this,
                                                      (ok) => {
                Attraction.City.FlightBooked = ok;
                IsFlighBooked.Hidden = (!Attraction.City.FlightBooked);
            });
        }

        partial void GetDirections (NSObject sender)
        {
            // Ask user to add directions
            AlertViewController.PresentOKCancelAlert ("Add Directions",
                                                     string.Format ("Would you like to add directions to {0} to you itinerary?", Attraction.Name),
                                                     this,
                                                     (ok) => {
                                                         Attraction.AddDirections = ok;
                                                         IsDirections.Hidden = (!Attraction.AddDirections);
                                                     });
        }

        partial void MarkFavorite (NSObject sender)
        {
            // Flip favorite state
            Attraction.IsFavorite = (!Attraction.IsFavorite);
            IsFavorite.Hidden = (!Attraction.IsFavorite);

            // Reload table
            SplitView.Master.TableController.TableView.ReloadData ();
        }
        #endregion
    }
}

여기서는 속성으로 표시 되는 인력 (AttractionInformation)를 제공 하 고, 인터페이스 디자이너에서 뷰에 추가 된 UI 위젯을 채우는 UpdateUI 메서드를 만들었습니다.Here, we have supplied the Attraction (AttractionInformation) being displayed as a property and created a UpdateUI method that populates the UI Widgets added to the View in the Interface Designer.

또한 변경 내용을 테이블 뷰 (AcctractionTableView)로 다시 전달 하는 데 사용할 분할 뷰 컨트롤러 (SplitView)에 대 한 바로 가기를 정의 했습니다.We have also defined a shortcut back to the Split View Controller (SplitView) that we will use to communicate changes back to the Table View (AcctractionTableView).

마지막으로 사용자 지정 작업 (이벤트)이 인터페이스 디자이너에서 만든 3 개의 UIButton 인스턴스에 추가 되었습니다. 그러면 사용자가 인력를 _즐겨찾기로_표시 하 고, 인력에 대 한 지침 을 가져오고, 지정 된 도시에 비행 을 이동할 수 있습니다.Finally, custom Actions (events) were added to the three UIButton instances created in the Interface Designer, that allow the user to mark an attraction as a Favorite, get Directions to an attraction and Book a Flight to a given city.

탐색 뷰 컨트롤러The Navigation View Controller

테이블 뷰 컨트롤러는 분할 뷰의 왼쪽에 있는 탐색 뷰 컨트롤러에 중첩 되기 때문에 탐색 뷰 컨트롤러에는 인터페이스 디자이너의 사용자 지정 클래스 (MasterNavigationController)가 할당 되 고 다음과 같이 정의 됩니다.Because the Table View Controller is nested in a Navigation View Controller in the left side of the Split View, the Navigation View Controller was assigned a custom class (MasterNavigationController) in the Interface Designer and defined as follows:

using System;
using Foundation;
using UIKit;

namespace tvTable
{
    public partial class MasterNavigationController : UINavigationController
    {
        #region Computed Properties
        public MasterSplitView SplitView { get; set;}
        public AttractionTableViewController TableController {
            get { return TopViewController as AttractionTableViewController; }
        }
        #endregion

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

이 클래스는 분할 뷰 컨트롤러의 두 면에서 보다 쉽게 통신할 수 있도록 몇 가지 바로 가기를 정의 하기만 합니다.Again, this class just defines a few shortcuts to make it easier to communicate across the two sides of the Split View Controller:

  • SplitView-탐색 뷰 컨트롤러가 속한 분할 뷰 컨트롤러 (MainSpiltViewController)에 대 한 링크입니다.SplitView - Is a link to the Split View Controller (MainSpiltViewController) that the Navigation View Controller belongs to.
  • TableController-탐색 뷰 컨트롤러의 최상위 뷰로 표시 되는AttractionTableViewController(테이블 뷰 컨트롤러)를 가져옵니다.TableController - Gets the Table View Controller (AttractionTableViewController) that is presented as the Top View in the Navigation View Controller.

분할 뷰 컨트롤러The Split View Controller

분할 뷰 컨트롤러는 응용 프로그램의 기반이 기 때문에 인터페이스 디자이너에서 해당 클래스에 대 한 사용자 지정 클래스 (MasterSplitViewController)를 만들고 다음과 같이 정의 했습니다.Because the Split View Controller is the base of our application, we created a custom class (MasterSplitViewController) for it in the Interface Designer and defined it as follows:

using System;
using Foundation;
using UIKit;

namespace tvTable
{
    public partial class MasterSplitView : UISplitViewController
    {
        #region Computed Properties
        public AttractionViewController Details {
            get { return ViewControllers [1] as AttractionViewController; }
        }

        public MasterNavigationController Master {
            get { return ViewControllers [0] as MasterNavigationController; }
        }
        #endregion

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

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

            // Initialize
            Master.SplitView = this;
            Details.SplitView = this;

            // Wire-up events
            Master.TableController.TableDelegate.AttractionHighlighted += (attraction) => {
                // Display new attraction
                Details.Attraction = attraction;
            };
        }
        #endregion
    }
}

먼저 분할 보기 (AttractionViewController)의 세부 정보 쪽 및 마스터 쪽 (MasterNavigationController)에 대 한 바로 가기를 만듭니다.First, we create shortcuts to the Details side of the Split View (AttractionViewController) and to the Master side (MasterNavigationController). 이를 통해 나중에 두 쪽 간에 더 쉽게 통신할 수 있습니다.Again, this makes it easier to communicate between the two sides later.

그런 다음 분할 뷰가 메모리에 로드 되 면 분할 보기의 양쪽에 분할 뷰 컨트롤러를 연결 하 고 인력AttractionHighlighted(테이블 보기)의 사용자에 게 응답 합니다. 여기에는 새 인력 를 표시 합니다 . 분할 뷰.Next, when the Split View is loaded into memory, we attach the Split View Controller to both sides of the Split View and respond to the user highlighting an attraction in the Table View (AttractionHighlighted) by displaying the new attraction in the Details side of the Split View.

분할 뷰 내에서 테이블 뷰의 전체 구현을 보려면 tvTables 샘플 앱을 참조 하세요.Please see the tvTables sample app for a full implementation of Table Views inside of a Split View.

테이블 보기 세부 정보Table Views in Detail

TvOS는 iOS의 기반 이므로 테이블 뷰와 테이블 뷰 컨트롤러는 비슷한 방식으로 디자인 되 고 동작 합니다.Since tvOS is based off of iOS, Table Views and Table View Controllers are designed and behave in a similar fashion. Xamarin 앱에서 테이블 뷰로 작업 하는 방법에 대 한 자세한 내용은 iOS 테이블 및 셀 작업 설명서를 참조 하세요.For more detailed information on working with Table View in a Xamarin app, please see our iOS Working with Tables and Cells documentation.

요약Summary

이 문서에서는 tvOS 앱 내에서 테이블 뷰를 디자인 하 고 작업 하는 방법에 대해 설명 했습니다.This article has covered designing and working with Table Views inside of a Xamarin.tvOS app. 및는 tvOS 앱에서 테이블 뷰의 일반적인 사용 인 분할 뷰 내의 테이블 뷰로 작업 하는 예를 제공 했습니다.And has presented an example of working with a Table View inside of a Split View, which is the typical usage of a Table View in a tvOS app.