Работа с представлениями коллекции tvOS в Xamarin

Представления коллекции позволяют отображать группу содержимого с помощью произвольных макетов. Используя встроенную поддержку, они позволяют легко создавать сетку, например или линейные макеты, а также поддерживать пользовательские макеты.

Пример представления коллекции

Представление коллекции поддерживает коллекцию элементов с помощью делегата и источника данных для взаимодействия пользователя и содержимого коллекции. Так как представление коллекции основано на подсистеме макета, которая не зависит от самого представления, предоставляя другой макет, можно легко изменить представление данных представления коллекции во всплывающем режиме.

Сведения о представлениях коллекции

Как указано выше, представление коллекции (UICollectionView) управляет упорядоченной коллекцией элементов и представляет эти элементы с настраиваемыми макетами. Представления коллекции работают аналогично представлениям таблиц (UITableView), за исключением того, что они могут использовать макеты для представления элементов в нескольких столбцах.

При использовании представления коллекции в tvOS приложение отвечает за предоставление данных, связанных с коллекцией, с помощью источника данных (UICollectionViewDataSource). При необходимости данные представления коллекции можно упорядочить и представить в разные группы (разделы).

Представление коллекции представляет отдельные элементы на экране с помощью ячейки (UICollectionViewCell), которая предоставляет представление заданной части информации из коллекции (например, изображение и его название).

При необходимости дополнительные представления можно добавить в презентацию представления коллекции, чтобы выступать в качестве верхних и нижних колонтитулов для разделов и ячеек. Макет представления коллекции отвечает за определение размещения этих представлений вместе с отдельными ячейками.

Представление коллекции может реагировать на взаимодействие с пользователем с помощью делегата (UICollectionViewDelegate). Этот делегат также отвечает за определение того, может ли данная ячейка получить фокус, если выделена ячейка или выбрана. В некоторых случаях делегат определяет размер отдельных ячеек.

Макеты представления коллекции

Ключевой особенностью представления коллекции является его разделение между данными, которые он представляет, и его макетом. Макет представления коллекции (UICollectionViewLayout) отвечает за предоставление организации и расположения ячеек (и любых дополнительных представлений) в представлении на экране представления коллекции.

Отдельные ячейки создаются представлением коллекции из присоединенного источника данных, а затем упорядочиываются и отображаются заданным макетом представления коллекции.

Макет представления коллекции обычно предоставляется при создании представления коллекции. Однако макет представления коллекции можно изменить в любое время, а экранная презентация данных представления коллекции будет автоматически обновляться с помощью нового макета.

Макет представления коллекции предоставляет несколько методов, которые можно использовать для анимации перехода между двумя разными макетами (по умолчанию анимация не выполняется). Кроме того, макеты представлений коллекции могут работать с распознавателями жестов для дальнейшего анимации взаимодействия пользователя, что приводит к изменению макета.

Создание ячеек и дополнительных представлений

Источник данных представления коллекции не только отвечает за предоставление данных, поддерживающих элемент коллекции, но и ячейки, используемые для отображения содержимого.

Так как представления коллекции были разработаны для обработки больших коллекций элементов, отдельные ячейки можно откружать и повторно использовать, чтобы не перерасходить ограничения памяти. Существует два разных метода для отмены представлений:

  • DequeueReusableCell — создает или возвращает ячейку заданного типа (как указано в раскадровке приложения).
  • DequeueReusableSupplementaryView — создает или возвращает дополнительное представление заданного типа (как указано в раскадровки приложения).

Перед вызовом любого из этих методов необходимо зарегистрировать класс, раскадровку или .xib файл, используемый для создания представления ячейки в представлении коллекции. Например:

public CityCollectionView (IntPtr handle) : base (handle)
{
    // Initialize
    RegisterClassForCell (typeof(CityCollectionViewCell), CityViewDatasource.CardCellId);
    ...
}

Где typeof(CityCollectionViewCell) предоставляет класс, поддерживающий представление и CityViewDatasource.CardCellId предоставляющий идентификатор, используемый при отмене ячейки (или представления).

После того как ячейка будет отложена, вы настроите ее с данными для элемента, который он представляет, и вернитесь в представление коллекции для отображения.

Сведения о контроллерах представления коллекции

Контроллер представления коллекции (UICollectionViewController) — это специализированный контроллер представления (UIViewController), который обеспечивает следующее поведение:

  • Он отвечает за загрузку представления коллекции из раскадровки или .xib файла и создания экземпляра представления. Если он создан в коде, он автоматически создает новое ненастроенное представление коллекции.
  • После загрузки представления коллекции контроллер пытается загрузить свой источник данных и делегат из раскадровки или .xib файла. Если ни один из них недоступен, он задает себя как источник обоих.
  • Убедитесь, что данные загружаются перед заполнением представления коллекции при первом отображении, а также перезагружаются и очищают выбор на каждом последующем экране.

Кроме того, контроллер представления коллекции предоставляет переопределимые методы, которые можно использовать для управления жизненным циклом представления коллекции, AwakeFromNib например и ViewWillDisplay.

Представления коллекции и раскадровки

Самый простой способ работы с представлением коллекции в приложении Xamarin.tvOS — добавить его в раскадровку. В качестве краткого примера мы создадим пример приложения, представляющее изображение, заголовок и кнопку выбора. Если пользователь нажимает кнопку выбора, откроется представление коллекции, позволяющее пользователю выбрать новое изображение. При выборе изображения представление коллекции закрывается, а новое изображение и заголовок будут отображаться.

Давайте сделаем следующее:

  1. Запустите новое приложение с одним представлением tvOS в Visual Studio для Mac.

  2. В Обозреватель решений дважды щелкните Main.storyboard файл и откройте его в конструкторе iOS.

  3. Добавьте представление изображения, метку и кнопку в существующее представление и настройте их следующим образом:

    Пример макета

  4. Назначьте имя представлению изображения и метке на вкладке"Мини-приложение" Обозреватель свойств. Например:

    Задание имени

  5. Затем перетащите контроллер представления коллекции на раскадровку:

    Контроллер представления коллекции

  6. Перетащите элемент управления из кнопки в контроллер представления коллекции и выберите "Отправить " из всплывающего окна:

    Выберите

  7. При запуске приложения будет отображаться представление коллекции всякий раз, когда пользователь нажимает кнопку.

  8. Выберите представление коллекции и введите следующие значения на вкладке"Макет" Обозреватель свойств:

    Свойства Обозреватель

  9. Это определяет размер отдельных ячеек и границ между ячейками и внешним краем представления коллекции.

  10. Выберите контроллер представления коллекции и установите его класс CityCollectionViewController на вкладке "Мини-приложение":

    Задайте для класса значение CityCollectionViewController

  11. Выберите представление коллекции и задайте его класс CityCollectionView на вкладке "Мини-приложение":

    Задайте для класса значение CityCollectionView

  12. Выберите ячейку представления коллекции и задайте его класс CityCollectionViewCell на вкладке "Мини-приложение":

    Задайте для класса значение CityCollectionViewCell

  13. На вкладке "Мини-приложение" убедитесь, что макет и Flow направление прокрутки предназначено Vertical для представления коллекции:

    Вкладка мини-приложения

  14. Выберите ячейку представления коллекции и установите его удостоверениеCityCell на вкладке "Мини-приложение":

    Установка идентификатора в CityCell

  15. Сохранение изменений.

Если бы мы выбрали Custom для макета представления коллекции, можно было бы указать пользовательский макет. Apple предоставляет встроенный UICollectionViewFlowLayout интерфейс и UICollectionViewDelegateFlowLayout может легко представлять данные в макете на основе сетки (они используются в стиле макета flow ).

Дополнительные сведения о работе с раскадровками см. в руководстве по началу работы с раскадровки Hello, tvOS.

Предоставление данных для представления коллекции

Теперь, когда мы добавили представление коллекции (и контроллер представления коллекции) в раскадровку, необходимо предоставить данные для коллекции.

Модель данных

Во-первых, мы создадим модель для наших данных, которая содержит имя файла для отображаемого изображения, название и флаг для выбора города.

CityInfo Создайте класс и сделайте его следующим образом:

using System;

namespace tvCollection
{
    public class CityInfo
    {
        #region Computed Properties
        public string ImageFilename { get; set; }
        public string Title { get; set; }
        public bool CanSelect{ get; set; }
        #endregion

        #region Constructors
        public CityInfo (string filename, string title, bool canSelect)
        {
            // Initialize
            this.ImageFilename = filename;
            this.Title = title;
            this.CanSelect = canSelect;
        }
        #endregion
    }
}

Ячейка представления коллекции

Теперь необходимо определить способ представления данных для каждой ячейки. Измените CityCollectionViewCell.cs файл (созданный для вас автоматически из раскадровки) и сделайте его следующим образом:

using System;
using Foundation;
using UIKit;
using CoreGraphics;

namespace tvCollection
{
    public partial class CityCollectionViewCell : UICollectionViewCell
    {
        #region Private Variables
        private CityInfo _city;
        #endregion

        #region Computed Properties
        public UIImageView CityView { get ; set; }
        public UILabel CityTitle { get; set; }

        public CityInfo City {
            get { return _city; }
            set {
                _city = value;
                CityView.Image = UIImage.FromFile (City.ImageFilename);
                CityView.Alpha = (City.CanSelect) ? 1.0f : 0.5f;
                CityTitle.Text = City.Title;
            }
        }
        #endregion

        #region Constructors
        public CityCollectionViewCell (IntPtr handle) : base (handle)
        {
            // Initialize
            CityView = new UIImageView(new CGRect(22, 19, 320, 171));
            CityView.AdjustsImageWhenAncestorFocused = true;
            AddSubview (CityView);

            CityTitle = new UILabel (new CGRect (22, 209, 320, 21)) {
                TextAlignment = UITextAlignment.Center,
                TextColor = UIColor.White,
                Alpha = 0.0f
            };
            AddSubview (CityTitle);
        }
        #endregion


    }
}

Для нашего приложения tvOS мы будем отображать изображение и необязательное название. Если не удается выбрать указанный город, мы не удаляем представление изображения с помощью следующего кода:

CityView.Alpha = (City.CanSelect) ? 1.0f : 0.5f;

Если ячейка, содержащая изображение, сосредоточена пользователем, мы хотим использовать встроенный эффект Parallax для него, задав следующее свойство:

CityView.AdjustsImageWhenAncestorFocused = true;

Дополнительные сведения о навигации и фокусе см. в документации по работе с навигацией и фокусоми Siri Remote и Bluetooth Controllers .

Поставщик данных представления коллекции

С помощью модели данных, созданной и определяемой макетом ячейки, давайте создадим источник данных для представления коллекции. Источник данных будет отвечать не только за предоставление резервных данных, но и вывод ячеек для отображения отдельных ячеек на экране.

CityViewDatasource Создайте класс и сделайте его следующим образом:

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

namespace tvCollection
{
    public class CityViewDatasource : UICollectionViewDataSource
    {
        #region Application Access
        public static AppDelegate App {
            get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
        }
        #endregion

        #region Static Constants
        public static NSString CardCellId = new NSString ("CityCell");
        #endregion

        #region Computed Properties
        public List<CityInfo> Cities { get; set; } = new List<CityInfo>();
        public CityCollectionView ViewController { get; set; }
        #endregion

        #region Constructors
        public CityViewDatasource (CityCollectionView controller)
        {
            // Initialize
            this.ViewController = controller;
            PopulateCities ();
        }
        #endregion

        #region Public Methods
        public void PopulateCities() {

            // Clear existing cities
            Cities.Clear();

            // Add new cities
            Cities.Add(new CityInfo("City01.jpg", "Houses by Water", false));
            Cities.Add(new CityInfo("City02.jpg", "Turning Circle", true));
            Cities.Add(new CityInfo("City03.jpg", "Skyline at Night", true));
            Cities.Add(new CityInfo("City04.jpg", "Golden Gate Bridge", true));
            Cities.Add(new CityInfo("City05.jpg", "Roads by Night", true));
            Cities.Add(new CityInfo("City06.jpg", "Church Domes", true));
            Cities.Add(new CityInfo("City07.jpg", "Mountain Lights", true));
            Cities.Add(new CityInfo("City08.jpg", "City Scene", false));
            Cities.Add(new CityInfo("City09.jpg", "House in Winter", true));
            Cities.Add(new CityInfo("City10.jpg", "By the Lake", true));
            Cities.Add(new CityInfo("City11.jpg", "At the Dome", true));
            Cities.Add(new CityInfo("City12.jpg", "Cityscape", true));
            Cities.Add(new CityInfo("City13.jpg", "Model City", true));
            Cities.Add(new CityInfo("City14.jpg", "Taxi, Taxi!", true));
            Cities.Add(new CityInfo("City15.jpg", "On the Sidewalk", true));
            Cities.Add(new CityInfo("City16.jpg", "Midnight Walk", true));
            Cities.Add(new CityInfo("City17.jpg", "Lunchtime Cafe", true));
            Cities.Add(new CityInfo("City18.jpg", "Coffee Shop", true));
            Cities.Add(new CityInfo("City19.jpg", "Rustic Tavern", true));
        }
        #endregion

        #region Override Methods
        public override nint NumberOfSections (UICollectionView collectionView)
        {
            return 1;
        }

        public override nint GetItemsCount (UICollectionView collectionView, nint section)
        {
            return Cities.Count;
        }

        public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath)
        {
            var cityCell = (CityCollectionViewCell)collectionView.DequeueReusableCell (CardCellId, indexPath);
            var city = Cities [indexPath.Row];

            // Initialize city
            cityCell.City = city;

            return cityCell;
        }
        #endregion
    }
}

Давайте подробно рассмотрим этот класс. Во-первых, мы наследуем и UICollectionViewDataSource предоставляем ярлык идентификатору ячеек (что мы назначили в конструкторе iOS):

public static NSString CardCellId = new NSString ("CityCell");

Далее мы предоставляем хранилище для данных коллекции и предоставляем класс для заполнения данных:

public List<CityInfo> Cities { get; set; } = new List<CityInfo>();
...

public void PopulateCities() {

    // Clear existing cities
    Cities.Clear();

    // Add new cities
    Cities.Add(new CityInfo("City01.jpg", "Houses by Water", false));
    Cities.Add(new CityInfo("City02.jpg", "Turning Circle", true));
    ...
}

Затем мы переопределим NumberOfSections метод и возвращаем количество разделов (групп элементов), которые есть в представлении коллекции. В этом случае существует только один:

public override nint NumberOfSections (UICollectionView collectionView)
{
    return 1;
}

Затем мы возвращаем количество элементов в нашей коллекции с помощью следующего кода:

public override nint GetItemsCount (UICollectionView collectionView, nint section)
{
    return Cities.Count;
}

Наконец, мы отменим повторно используемый ячейку при запросе представления коллекции со следующим кодом:

public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath)
{
    var cityCell = (CityCollectionViewCell)collectionView.DequeueReusableCell (CardCellId, indexPath);
    var city = Cities [indexPath.Row];

    // Initialize city
    cityCell.City = city;

    return cityCell;
}

После получения ячейки представления коллекции типа CityCollectionViewCell мы заполняем его заданным элементом.

Реагирование на события пользователя

Так как мы хотим, чтобы пользователь мог выбрать элемент из коллекции, нам нужно предоставить делегат представления коллекции для обработки этого взаимодействия. И нам нужно предоставить способ сообщить нашему вызывающому представлению узнать, какой элемент выбран пользователем.

Делегат приложения

Нам нужен способ связать выбранный в данный момент элемент из представления коллекции обратно с вызывающим представлением. Мы будем использовать пользовательское свойство на нашем AppDelegateсайте. Измените AppDelegate.cs файл и добавьте следующий код:

public CityInfo SelectedCity { get; set;} = new CityInfo("City02.jpg", "Turning Circle", true);

Это определяет свойство и задает город по умолчанию, который изначально будет отображаться. Позже мы будем использовать это свойство для отображения выбора пользователя и разрешения изменения выбора.

Делегат представления коллекции

Затем добавьте новый CityViewDelegate класс в проект и сделайте его следующим образом:

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

namespace tvCollection
{
    public class CityViewDelegate : UICollectionViewDelegateFlowLayout
    {
        #region Application Access
        public static AppDelegate App {
            get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
        }
        #endregion

        #region Constructors
        public CityViewDelegate ()
        {
        }
        #endregion

        #region Override Methods
        public override CGSize GetSizeForItem (UICollectionView collectionView, UICollectionViewLayout layout, NSIndexPath indexPath)
        {
            return new CGSize (361, 256);
        }

        public override bool CanFocusItem (UICollectionView collectionView, NSIndexPath indexPath)
        {
            if (indexPath == null) {
                return false;
            } else {
                var controller = collectionView as CityCollectionView;
                return controller.Source.Cities[indexPath.Row].CanSelect;
            }
        }

        public override void ItemSelected (UICollectionView collectionView, NSIndexPath indexPath)
        {
            var controller = collectionView as CityCollectionView;
            App.SelectedCity = controller.Source.Cities [indexPath.Row];

            // Close Collection
            controller.ParentController.DismissViewController(true,null);
        }
        #endregion
    }
}

Давайте рассмотрим этот класс более подробно. Во-первых, мы наследуем от UICollectionViewDelegateFlowLayout. Причина, по которой мы наследуем этот класс, а не то, что мы используем встроенную UICollectionViewFlowLayout для представления наших элементов, а UICollectionViewDelegate не пользовательского типа макета.

Затем мы возвращаем размер отдельных элементов с помощью этого кода:

public override CGSize GetSizeForItem (UICollectionView collectionView, UICollectionViewLayout layout, NSIndexPath indexPath)
{
    return new CGSize (361, 256);
}

Затем мы определим, может ли данная ячейка получить фокус с помощью следующего кода:

public override bool CanFocusItem (UICollectionView collectionView, NSIndexPath indexPath)
{
    if (indexPath == null) {
        return false;
    } else {
        var controller = collectionView as CityCollectionView;
        return controller.Source.Cities[indexPath.Row].CanSelect;
    }
}

Мы проверка, чтобы узнать, имеет ли заданный фрагмент резервных данных его CanSelect флаг и true возвращает это значение. Дополнительные сведения о навигации и фокусе см. в документации по работе с навигацией и фокусоми Siri Remote и Bluetooth Controllers .

Наконец, мы отвечаем на запрос пользователя, выбрав элемент со следующим кодом:

public override void ItemSelected (UICollectionView collectionView, NSIndexPath indexPath)
{
    var controller = collectionView as CityCollectionView;
    App.SelectedCity = controller.Source.Cities [indexPath.Row];

    // Close Collection
    controller.ParentController.DismissViewController(true,null);
}

Здесь мы задали SelectedCity свойство элемента AppDelegate , выбранного пользователем, и мы закрываем контроллер представления коллекции, возвращаясь к представлению, вызываемого нами. Мы еще не определили ParentController свойство представления коллекции, мы сделаем это дальше.

Настройка представления коллекции

Теперь нам нужно изменить представление коллекции и назначить источник данных и делегат. Измените CityCollectionView.cs файл (созданный для нас автоматически из раскадровки) и сделайте его следующим образом:

using System;
using Foundation;
using UIKit;

namespace tvCollection
{
    public partial class CityCollectionView : UICollectionView
    {
        #region Application Access
        public static AppDelegate App {
            get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
        }
        #endregion

        #region Computed Properties
        public CityViewDatasource Source {
            get { return DataSource as CityViewDatasource;}
        }

        public CityCollectionViewController ParentController { get; set;}
        #endregion

        #region Constructors
        public CityCollectionView (IntPtr handle) : base (handle)
        {
            // Initialize
            RegisterClassForCell (typeof(CityCollectionViewCell), CityViewDatasource.CardCellId);
            DataSource = new CityViewDatasource (this);
            Delegate = new CityViewDelegate ();
        }
        #endregion

        #region Override Methods
        public override nint NumberOfSections ()
        {
            return 1;
        }

        public override void DidUpdateFocus (UIFocusUpdateContext context, UIFocusAnimationCoordinator coordinator)
        {
            var previousItem = context.PreviouslyFocusedView as CityCollectionViewCell;
            if (previousItem != null) {
                Animate (0.2, () => {
                    previousItem.CityTitle.Alpha = 0.0f;
                });
            }

            var nextItem = context.NextFocusedView as CityCollectionViewCell;
            if (nextItem != null) {
                Animate (0.2, () => {
                    nextItem.CityTitle.Alpha = 1.0f;
                });
            }
        }
        #endregion
    }
}

Во-первых, мы предоставляем ярлык для доступа к нашим AppDelegate:

public static AppDelegate App {
    get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
}

Затем мы предоставляем ярлык для источника данных представления коллекции и свойства для доступа к контроллеру представления коллекции (используется нашим делегатом выше для закрытия коллекции при выборе пользователем):

public CityViewDatasource Source {
    get { return DataSource as CityViewDatasource;}
}

public CityCollectionViewController ParentController { get; set;}

Затем мы используем следующий код для инициализации представления коллекции и назначения класса ячейки, источника данных и делегата:

public CityCollectionView (IntPtr handle) : base (handle)
{
    // Initialize
    RegisterClassForCell (typeof(CityCollectionViewCell), CityViewDatasource.CardCellId);
    DataSource = new CityViewDatasource (this);
    Delegate = new CityViewDelegate ();
}

Наконец, мы хотим, чтобы заголовок под изображением отображался только при выделении пользователем (в фокусе). Мы делаем это с помощью следующего кода:

public override void DidUpdateFocus (UIFocusUpdateContext context, UIFocusAnimationCoordinator coordinator)
{
    var previousItem = context.PreviouslyFocusedView as CityCollectionViewCell;
    if (previousItem != null) {
        Animate (0.2, () => {
            previousItem.CityTitle.Alpha = 0.0f;
        });
    }

    var nextItem = context.NextFocusedView as CityCollectionViewCell;
    if (nextItem != null) {
        Animate (0.2, () => {
            nextItem.CityTitle.Alpha = 1.0f;
        });
    }
}

Мы устанавливаем прозрачность предыдущего элемента, потеряющего фокус на нуле (0), и прозрачность следующего элемента получает фокус на 100 %. Эти переходы также анимированы.

Настройка контроллера представления коллекции

Теперь необходимо выполнить окончательную конфигурацию в представлении коллекции и разрешить контроллеру задать свойство, которое мы определили, чтобы представление коллекции можно было закрыть после того, как пользователь сделает выбор.

Измените CityCollectionViewController.cs файл (созданный автоматически из раскадровки) и сделайте его следующим образом:

// This file has been autogenerated from a class added in the UI designer.

using System;

using Foundation;
using UIKit;

namespace tvCollection
{
    public partial class CityCollectionViewController : UICollectionViewController
    {
        #region Computed Properties
        public CityCollectionView Collection {
            get { return CollectionView as CityCollectionView; }
        }
        #endregion

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

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

            // Save link to controller
            Collection.ParentController = this;
        }
        #endregion
    }
}

Сложив все вместе

Теперь, когда у нас есть все части, которые объединяются для заполнения и управления представлением коллекции, нам нужно сделать окончательные изменения в нашем главном представлении, чтобы объединить все.

Измените ViewController.cs файл (созданный автоматически из раскадровки) и сделайте его следующим образом:

using System;
using Foundation;
using UIKit;
using tvCollection;

namespace MySingleView
{
    public partial class ViewController : UIViewController
    {
        #region Application Access
        public static AppDelegate App {
            get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
        }
        #endregion

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

        #region Override Methods
        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();
            // Perform any additional setup after loading the view, typically from a nib.
        }

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

            // Update image with the currently selected one
            CityView.Image = UIImage.FromFile(App.SelectedCity.ImageFilename);
            BackgroundView.Image = CityView.Image;
            CityTitle.Text = App.SelectedCity.Title;
        }

        public override void DidReceiveMemoryWarning ()
        {
            base.DidReceiveMemoryWarning ();
            // Release any cached data, images, etc that aren't in use.
        }
        #endregion
    }
}

Следующий код изначально отображает выбранный элемент из SelectedCity свойства AppDelegate и переиграет его, когда пользователь сделал выбор из представления коллекции:

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

    // Update image with the currently selected one
    CityView.Image = UIImage.FromFile(App.SelectedCity.ImageFilename);
    BackgroundView.Image = CityView.Image;
    CityTitle.Text = App.SelectedCity.Title;
}

Проверка приложения

Если вы создаете и запускаете приложение, основное представление отображается в городе по умолчанию:

Основной экран

Если пользователь нажимает кнопку "Выбрать представление" , откроется представление коллекции:

Представление коллекции

Любой город с заданным CanSelectfalse свойством будет отображаться неактивным, и пользователь не сможет задать фокус на нем. Когда пользователь выделяет элемент (сделать его в фокусе) отображается заголовок, и он может использовать эффект Parallax для тонкости наклона изображения в трехмерном формате.

Когда пользователь щелкает изображение выбора, представление коллекции закрывается, а основное представление переигрывается с новым изображением:

Новое изображение на начальном экране

Создание пользовательских макетов и изменение порядка элементов

Одним из ключевых функций использования представления коллекции является возможность создания пользовательских макетов. Так как tvOS наследует от iOS, процесс создания пользовательского макета одинаков. Дополнительные сведения см. в документации по представлениям коллекций.

Недавно добавленные в представления коллекции для iOS 9 были возможность легко разрешить переупорядочение элементов в коллекции. Опять же, так как tvOS 9 является подмножеством iOS 9, это делается так же. Дополнительные сведения см. в документе "Изменения в представлении коллекции".

Итоги

В этой статье рассматривается проектирование и работа с представлениями коллекции в приложении Xamarin.tvOS. Во-первых, он обсудил все элементы, составляющие представление коллекции. Далее он показал, как разработать и реализовать представление коллекции с помощью раскадровки. Наконец, приведены ссылки на сведения о создании пользовательских макетов и переупорядочении элементов.