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

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

Хорошие новости - то, что, с точки зрения API, реализовывая пользовательский макет не является трудным. Самая твердая часть выполняет вычисления, должен был определить позиции элементов в расположении. Когда Вы знаете, что расположения тех элементов, предоставляя ту информацию представлению набора являются прямыми.

Разделение на подклассы UICollectionViewLayout

Для пользовательских макетов Вы хотите разделить на подклассы UICollectionViewLayout, который предоставляет Вам новую начальную точку для Вашего проекта. Только ряд методов обеспечивает базовое поведение для Вашего объекта расположения и требуется в Вашей реализации. Остальная часть методов там для Вас для переопределения по мере необходимости для тонкой настройки поведения расположения. Базовые методы обрабатывают следующие решающие задачи:

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

Объект расположения использует информацию, предоставленную ее источником данных для создания расположения представления набора. Ваше расположение связывается с источником данных вызывающими методами для collectionView свойство, которое доступно во всех методах расположения. Следует иметь в виду то, что Ваше представление набора знает и не знает во время процесса создания макета. Поскольку процесс создания макета идет полным ходом, представление набора не может отследить расположение или расположение представлений. Таким образом даже при том, что объект расположения не ограничит Вас в вызове ни одного из методов представления набора, рефрена от доверия представлению набора ни для чего кроме данных, необходимых для вычислений расположения.

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

Представление набора работает непосредственно с Вашим объектом пользовательского макета управлять полным процессом создания макета. Когда представление набора решает, что ему нужна информация макета, оно спрашивает Ваш объект расположения обеспечить его. Например, представление набора просит информацию макета, когда это сначала выведено на экран или изменено. Можно также сказать представлению набора обновлять свое расположение явно путем вызова invalidateLayout метод объекта расположения. Тот метод выбрасывает существующую информацию макета и вызывает объект расположения генерировать новую информацию макета.

Во время процесса создания макета представление набора вызывает определенные методы Вашего объекта расположения. Эти методы являются Вашим шансом вычислить позицию элементов и предоставить представлению набора основную информацию, в которой это нуждается. Другие методы можно вызвать, также, но эти методы всегда вызывают во время процесса создания макета в следующем порядке:

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

  2. Используйте collectionViewContentSize метод для возврата полного размера всей предметной области на основе начальных вычислений.

  3. Используйте layoutAttributesForElementsInRect: метод для возврата атрибутов для ячеек и представлений, которые находятся в указанном прямоугольнике.

Рисунок 5-1 иллюстрирует, как можно использовать предыдущие методы для генерации информации макета.

Рисунок 5-1  , Выкладывающий Ваше пользовательское содержание

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

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

На основе текущей позиции прокрутки представление набора тогда вызывает Ваш layoutAttributesForElementsInRect: метод для выяснения атрибуты ячеек и представлений в определенном прямоугольнике, который может или может не совпасть с видимым прямоугольником. После возврата той информации базовый процесс создания макета эффективно завершен.

После концов расположения атрибуты Ваших ячеек и представлений остаются тем же до Вас, или представление набора лишает законной силы расположение. Вызов invalidateLayout метод Вашего объекта расположения заставляет процесс создания макета начинаться снова, начиная с нового вызова к prepareLayout метод. Представление набора может также лишить законной силы Ваше расположение автоматически во время прокрутки. Если пользователь прокручивает его содержание, представление набора вызывает объект расположения shouldInvalidateLayoutForBoundsChange: если тот метод возвращается, метод и лишает законной силы расположение YES.

Создание атрибутов макета

Атрибуты возражают, что Ваше расположение ответственно за, экземпляры UICollectionViewLayoutAttributes класс. Эти экземпляры могут быть созданы во множестве различных методов в Вашем приложении. Когда Ваше приложение не имеет дело с тысячами элементов, оно целесообразно создавать эти экземпляры при подготовке расположения, потому что информация макета может кэшироваться и ссылаться, а не вычисляться на лету. Если затраты вычислений всех атрибутов передняя сторона перевешивает преимущества кэширования в Вашем приложении, столь же просто создать атрибуты в момент, когда их требуют.

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

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

После создания каждого объекта атрибутов, набор соответствующие атрибуты для соответствующего представления. Как минимум установите размер и позицию представления в расположении. В случаях, где представления Вашего перекрытия расположения, присвойте значение zIndex свойство для обеспечения непротиворечивого упорядочивания перекрывающихся представлений. Другие свойства позволяют Вам управлять видимостью или появлением ячейки или представлением и могут быть изменены по мере необходимости. Если стандартный класс атрибутов не удовлетворяет потребностям Вашего приложения, можно разделить на подклассы и развернуть его, чтобы хранить другую информацию о каждом представлении. При разделении на подклассы атрибутов макета требуется, что Вы реализуете isEqual: метод для сравнения Ваших пользовательских атрибутов, потому что представление набора использует этот метод для некоторых его операций.

Для получения дополнительной информации об атрибутах макета, посмотрите Ссылку класса UICollectionViewLayoutAttributes.

Подготовка расположения

В начале цикла расположения, вызовов объектов расположения prepareLayout прежде, чем начать процесс создания макета. Этот метод является Вашим шансом вычислить информацию, позже сообщающую Вашему расположению. prepareLayout метод не требуется, чтобы реализовывать пользовательский макет, но предоставлен как возможность сделать начальные вычисления при необходимости. После того, как этот метод вызывают, Ваше расположение должно иметь достаточно информации для вычисления размера содержания представления набора, следующего шага в процессе создания макета. Информация, однако, может колебаться от этого минимального требования до создания и хранить все объекты атрибутов макета, которые будет использовать Ваше расположение. Использование prepareLayout метод подвергается инфраструктуре Вашего приложения и к тому, что целесообразно вычислять переднюю сторону по сравнению с тем, что вычислить по запросу. Для примера какой prepareLayout метод мог бы быть похожим, видеть Подготовку Расположения.

Обеспечение атрибутов макета для элементов в данном прямоугольнике

Во время последнего шага процесса создания макета представление набора вызывает Ваш объект расположения layoutAttributesForElementsInRect: метод. Цель этого метода состоит в том, чтобы обеспечить атрибуты макета для каждой ячейки и каждого дополнительного представления или представления художественного оформления, пересекающего указанный прямоугольник. Для большой предметной области с возможностью прокрутки представление набора может просто попросить атрибуты элементов в части той предметной области, которая в настоящее время видима. На рисунке 5-2 в настоящее время видимое содержание, для которого Ваш объект расположения должен создать объекты атрибута, является ячейками 6 - 20 вместе со вторым представлением заголовка. Вы должны быть подготовлены обеспечить, атрибуты макета для любой части Вашего набора просматривают предметную область. Такие атрибуты могли бы использоваться для упрощения анимаций для вставленных или удаленных элементов.

Рисунок 5-2  , Излагающий только видимые представления

Поскольку layoutAttributesForElementsInRect: метод вызывают после Вашего объекта расположения prepareLayout метод, у Вас должна уже быть большая часть информации, в которой Вы нуждаетесь, чтобы возвратить или создать требуемые атрибуты. Реализация Вашего layoutAttributesForElementsInRect: метод выполняет эти шаги:

  1. Выполните итерации по данным, сгенерированным prepareLayout метод, чтобы или получить доступ к кэшируемым атрибутам или создать новые.

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

  3. Для каждого элемента пересечения добавьте соответствие UICollectionViewLayoutAttributes возразите против массива.

  4. Возвратите массив атрибутов макета к представлению набора.

В зависимости от того, как Вы управляете своей информацией макета, Вы могли бы создать UICollectionViewLayoutAttributes объекты в Вашем prepareLayout метод или ожидает и выполняет в нем Ваш layoutAttributesForElementsInRect: метод. При формировании реализации, соответствующей потребности приложения, имейте в виду преимущества кэширования информации макета. Вычисления новых атрибутов макета неоднократно для ячеек являются дорогой работой, та, которая может иметь заметно неблагоприятные эффекты на производительность Вашего приложения. Однако когда сумма элементов, которыми управляет Ваше представление набора, является большой, может иметь больше смысла (для производительности) создавать атрибуты макета, когда требуется. Это - просто вопрос выяснения, какая стратегия имеет большую часть смысла для Вашего приложения.

Для определенного примера того, как можно было бы реализовать layoutAttributesForElementsInRect:, посмотрите Обеспечение Атрибутов макета.

Обеспечение атрибутов макета по требованию

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

Ваша реализация этих методов должна получить атрибуты текущего макета для данной ячейки или представления. Каждый объект пользовательского макета, как ожидают, реализует layoutAttributesForItemAtIndexPath: метод. Если Ваше расположение не содержит дополнительных представлений, Вы не должны переопределять layoutAttributesForSupplementaryViewOfKind:atIndexPath: метод. Точно так же, если это не содержит представления художественного оформления, Вы не должны переопределять layoutAttributesForDecorationViewOfKind:atIndexPath: метод. При возврате атрибутов Вы не должны обновлять атрибуты макета. Если необходимо изменить информацию макета, лишить законной силы объект расположения и позволить ему обновить те данные во время последующего цикла расположения.

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

Существует два способа соединить Ваш пользовательский макет с представлением набора: программно или через раскадровки. Представление набора соединяется с его расположением через перезаписываемое свойство, collectionViewLayout. Для установки расположения в пользовательскую реализацию установите свойство макета представления набора в экземпляр объекта пользовательского макета. Перечисление 5-1 показывает строку необходимого кода.

Перечисление 5-1  , Соединяющее Ваш пользовательский макет

self.collectionView.collectionViewLayout = [[MyCustomLayout alloc] init];

Иначе, от Вашей раскадровки, откройте панель Document Outline и выберите Ваше представление набора (это перечислено в раскрывающем меню для Вашего контроллера). С выбранным представлением набора откройте инспектора Атрибутов в области Utilities, и под разделом маркированное изменение Представления Набора Параметр макета от Потока до Пользовательского. Опция ниже его изменяется от Направления Прокрутки до Класса, и можно теперь выбрать класс пользовательского макета.

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

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

Подъемное содержание посредством дополнительных представлений

Дополнительные представления являются отдельными от ячеек представления набора и имеют свой собственный набор атрибутов макета. Как ячейки, эти представления предоставлены по условию исходный объект, но их цель состоит в том, чтобы улучшить основное содержание Вашего приложения. Например, UICollectionViewFlowLayout использует дополнительные представления для заголовков раздела и нижних колонтитулов. Другое приложение могло использовать дополнительные представления для предоставления каждой ячейки владеть текстовой маркой для отображения информации о той ячейке. Как ячейки представления набора, дополнительные представления подвергаются процессу переработки для оптимизации суммы ресурсов, используемых представлением набора. Поэтому все дополнительные представления, используемые в Вашем приложении, должны быть разделены на подклассы от UICollectionReusableView класс.

Шаги для добавления дополнительных представлений к Вашим разметкам следующие:

  1. Зарегистрируйте свое дополнительное представление к объекту расположения представления набора, использующему любого registerClass:forSupplementaryViewOfKind:withReuseIdentifier: или registerNib:forSupplementaryViewOfKind:withReuseIdentifier: метод.

  2. В Вашем источнике данных, реализации collectionView:viewForSupplementaryElementOfKind:atIndexPath:. Поскольку эти представления являются допускающими повторное использование, вызвать dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath: исключить из очереди, или создать, новое допускающее повторное использование представление и установить любые необходимые данные прежде, чем возвратить его.

  3. Создайте объекты атрибутов макета для своих дополнительных представлений, как Вы делаете для ячеек.

  4. Включайте эти объекты атрибутов макета в массив атрибутов, возвращенных layoutAttributesForElementsInRect: метод.

  5. Реализуйте layoutAttributesForSupplementaryViewOfKind:atIndexPath: метод для возврата атрибутов возражает для указанного дополнительного представления каждый раз, когда запрошено.

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

Включая представления художественного оформления в Ваших пользовательских макетах

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

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

  1. Зарегистрируйте свое представление художественного оформления в объекте расположения использование registerClass:forDecorationViewOfKind: или registerNib:forDecorationViewOfKind: метод. Несмотря на то, что этот подход подобен регистрирующимся ячейкам и дополнительным представлениям, помните, что регистрация представлений художественного оформления происходит в объекте расположения, не в источнике данных.

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

  3. Реализуйте layoutAttributesForDecorationViewOfKind:atIndexPath: метод в Вашем расположении возражает и возвращает атрибуты для Ваших представлений художественного оформления, когда спросили.

  4. Дополнительно, реализуйте initialLayoutAttributesForAppearingDecorationElementOfKind:atIndexPath: и finalLayoutAttributesForDisappearingDecorationElementOfKind:atIndexPath: методы для обработки анимаций для появления и исчезновения представлений художественного оформления. Для получения дополнительной информации посмотрите Более интересные Анимации Вставки и Удаления Создания

Процесс создания для представлений художественного оформления отличается от процесса для ячеек и дополнительных представлений. Регистрация класса или файла пера является всем, что необходимо сделать, чтобы гарантировать, что представления художественного оформления создаются, когда они необходимы. Поскольку они чисто визуальны, для представлений художественного оформления, как ожидают, не будет нужна никакая конфигурация вне того, в чем уже выполняют предоставленный файл пера или объектом initWithFrame: метод. Поэтому, когда представление художественного оформления необходимо, представление набора создает его для Вас и применяет атрибуты, предоставленные объектом расположения. Любые представления художественного оформления должны все еще быть подклассом UICollectionReusableView потому что объект расположения использует механизм переработки для своих представлений художественного оформления.

Создание более интересных анимаций вставки и удаления

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

Чтобы понять, как начальная буква приписывает работу, она помогает видеть пример. Стартовое расположение (рисунок 5-3) показывает представление набора, первоначально содержащее только три ячейки. Когда новая ячейка вставляется, представление набора спрашивает объект расположения обеспечить начальные атрибуты для вставляемой ячейки. В этом случае объект расположения устанавливает начальную позицию ячейки к середине представления набора и устанавливает его альфа-значение в 0 для сокрытия его. Во время анимаций эта новая ячейка, кажется, постепенно появляется и перемещается из центра представления набора к его заключительной позиции в нижнем правом углу.

Рисунок 5-3  , Указывающий начальную букву, приписывает для появляющегося на экране элемента

Перечисление 5-2 показывает код, который Вы могли бы использовать для указания начальных атрибутов для вставленной ячейки от рисунка 5-3. Этот метод устанавливает позицию ячейки к центру представления набора и делает его прозрачным. Объект расположения тогда обеспечил бы заключительную позицию и альфу для ячейки как часть нормального процесса создания макета.

Перечисление 5-2  , Указывающее начальную букву, приписывает для вставленной ячейки

- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath {
   UICollectionViewLayoutAttributes* attributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath];
   attributes.alpha = 0.0;
 
   CGSize size = [self collectionView].frame.size;
   attributes.center = CGPointMake(size.width / 2.0, size.height / 2.0);
   return attributes;
}

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

Улучшение прокрутки опыта расположения

Ваш объект пользовательского макета может влиять на поведение прокрутки представления набора создать лучший пользовательский опыт. Когда связанные с прокруткой сенсорные события заканчиваются, представление прокрутки определяет место погребения содержания прокрутки на основе текущей скорости и уровня замедления в действительности. Когда представление набора знает, что расположение, спрашивает свой объект расположения, если расположение должно быть изменено путем вызова targetContentOffsetForProposedContentOffset:withScrollingVelocity: метод. Поскольку это вызывает этот метод, в то время как базовое содержание все еще перемещается, Ваш пользовательский макет может влиять на точку отдыха финала содержания прокрутки.

Рисунок 5-4 демонстрирует, как Вы могли бы использовать свой объект расположения изменить поведение прокрутки представления набора. Предположим, что смещение представления набора запускается в (0, 0), и пользователь сильно ударяет оставленный. Представление набора вычисляет, где прокрутка естественно остановила бы и обеспечивает то значение как «предложенное» значение смещения содержания. Ваш объект расположения мог бы изменить предложенное значение, чтобы гарантировать, что при прокрутке остановок, элемент центрируется точно в видимых границах представления набора. Это новое значение становится целевым смещением содержания и - то, что Вы возвращаете из Вашего targetContentOffsetForProposedContentOffset:withScrollingVelocity: метод.

Рисунок 5-4  , Изменяющий предложенное смещение содержания на более надлежащее значение

Подсказки для реализации Ваших пользовательских макетов

Вот некоторые подсказки и предложения для реализации Ваших объектов пользовательского макета: