Создание иерархии слоев

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

Расположение уровней в иерархию слоев

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

Добавление, вставка и удаление подуровней

Каждый расположенный на слое объект имеет методы для добавления, вставки и удаления подуровней. Таблица 4-1 суммирует эти методы и их поведение.

Табличные 4-1  Методы для изменения иерархии слоев

Поведение

Методы

Описание

Добавление уровней

addSublayer:

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

Вставка уровней

insertSublayer:above:

insertSublayer:atIndex:

insertSublayer:below:

Вставляет подуровня в иерархию подуровня в указанном индексе или в позиции относительно другого подуровня. При вставке выше или ниже другого подуровня Вы только указываете позицию подуровня в sublayers массив. Фактическая видимость уровней определяется прежде всего значением в их zPosition свойство и во вторую очередь их позицией в sublayers массив.

Удаление уровней

removeFromSuperlayer

Удаляет подуровня из его родительского слоя.

Обмен уровнями

replaceSublayer:with:

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

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

Расположение и калибровка подуровней

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

Вы устанавливаете размер подуровня с помощью bounds свойство и набор его позиция на его суперуровне с помощью position свойство. Источник прямоугольника границ почти всегда (0, 0), и размер является любым размером, который Вы хотите для уровня, указанного в точках. Значение в position свойство интерпретируется относительно точки привязки уровня, расположенной в центре уровня по умолчанию. Если Вы не присваиваете значения этим свойствам, Базовая Анимация устанавливает начальную ширину и высоту уровня к 0 и устанавливает позицию в (0, 0).

myLayer.bounds = CGRectMake(0, 0, 100, 100);
myLayer.position = CGPointMake(200, 200);

Как анимации влияния иерархий слоев

Некоторые суперсвойства слоя могут влиять на поведение любых анимаций, применился к его дочерним уровням. Одно такое свойство speed свойство, которое является множителем для скорости анимации. Значение этого свойства установлено в 1.0 по умолчанию, но изменение его к 2.0 анимации причин, чтобы работать на дважды их исходной скорости и таким образом закончиться в половину времени. Это свойство влияет не только на уровень, для которого оно установлено, но также и для подуровней того уровня. Такие изменения являются мультипликативными также. Если и подуровень и его суперуровень имеют скорость 2.0, анимации на подуровне достигают на четыре раза их исходной скорости.

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

Корректировка расположения иерархий слоев

Базовая Анимация поддерживает несколько опций для корректировки размера и позиции подуровней в ответ на изменения в их суперуровне. В iOS распространяющееся использование поддержанных уровнем представлений делает создание иерархий слоев менее важным; только ручные обновления расположения поддерживаются. Для OS X несколько других опций доступны, которые упрощают управлять Вашими иерархиями слоев.

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

Используя ограничения для управления иерархиями слоев в OS X

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

  1. Создайте один или больше CAConstraint объекты. Используйте те объекты определить параметры ограничения.

  2. Добавьте, что Ваше ограничение возражает против уровня, атрибуты которого они изменяют.

  3. Получите совместно используемое CAConstraintLayoutManager возразите и присвойтесь к непосредственному суперуровню.

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

  Ограничительный менеджер по расположению рисунка 4-1 атрибуты
Constraint layout manager attributes

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

При создании ограничений необходимо всегда указывать три данные:

  • Аспект уровня, который Вы хотите ограничить

  • Уровень для использования в качестве ссылки

  • Аспект эталонного слоя для использования в сравнении

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

Перечисление 4-1  , Определяющее простое ограничение

[myLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidY
                                                 relativeTo:@"superlayer"
                                                  attribute:kCAConstraintMidY]];

Для применения ограничений во время выполнения необходимо присоединить совместно используемое CAConstraintLayoutManager возразите против непосредственного суперуровня. Каждый уровень ответственен за управление расположением его подуровней. Присвоение менеджера по расположению к родителю говорит Базовой Анимации применять ограничения, определенные ее дочерними элементами. Менеджер по расположению объект применяет ограничения автоматически. После присвоения его к родительскому слою Вы не должны говорить ему обновлять расположение.

Чтобы видеть как ограничительная работа в более определенном сценарии, рассмотрите рисунок 4-2. В этом примере проект требует что ширина и высота layerA останьтесь неизменными и это layerA останьтесь в центре в его суперуровне. Кроме того, ширина layerB должен соответствовать тот из layerA, главный край layerB должен остаться 10 точками ниже базового края layerA, и базовый край layerB должен остаться 10 точками выше базового края суперуровня. Перечисление 4-2 показывает код, что Вы использовали бы для создания подуровней и ограничений для этого примера.

  Ограничения рисунка 4-2 В качестве примера базировали расположение
Example constraints based layoutExample constraints based layout

Перечисление 4-2  , Настраивающее ограничения для Ваших уровней

 
// Create and set a constraint layout manager for the parent layer.
theLayer.layoutManager=[CAConstraintLayoutManager layoutManager];
 
// Create the first sublayer.
CALayer *layerA = [CALayer layer];
layerA.name = @"layerA";
layerA.bounds = CGRectMake(0.0,0.0,100.0,25.0);
layerA.borderWidth = 2.0;
 
// Keep layerA centered by pinning its midpoint to its parent's midpoint.
[layerA addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidY
                                                 relativeTo:@"superlayer"
                                                  attribute:kCAConstraintMidY]];
[layerA addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidX
                                                 relativeTo:@"superlayer"
                                                  attribute:kCAConstraintMidX]];
[theLayer addSublayer:layerA];
 
// Create the second sublayer
CALayer *layerB = [CALayer layer];
layerB.name = @"layerB";
layerB.borderWidth = 2.0;
 
// Make the width of layerB match the width of layerA.
[layerB addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintWidth
                                                 relativeTo:@"layerA"
                                                  attribute:kCAConstraintWidth]];
 
// Make the horizontal midpoint of layerB match that of layerA
[layerB addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidX
                                                 relativeTo:@"layerA"
                                                  attribute:kCAConstraintMidX]];
 
// Position the top edge of layerB 10 points from the bottom edge of layerA.
[layerB addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxY
                                                 relativeTo:@"layerA"
                                                  attribute:kCAConstraintMinY
                                                     offset:-10.0]];
 
// Position the bottom edge of layerB 10 points
//  from the bottom edge of the parent layer.
[layerB addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinY
                                                 relativeTo:@"superlayer"
                                                  attribute:kCAConstraintMinY
                                                     offset:+10.0]];
 
[theLayer addSublayer:layerB];

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

Установка правил автоизменения размеров для Ваших иерархий слоев OS X

Автоизменяющие размеры правила являются другим способом скорректировать размер и позицию уровня в OS X. С автоизменением размеров правил Вы определяете, должны ли края Вашего уровня остаться на фиксированном или переменном расстоянии от соответствующих краев суперуровня. Можно так же определять, фиксируются ли ширина или высота уровня или переменная. Отношения всегда между уровнем и его суперуровнем. Вы не можете использовать правила автоизменения размеров указать отношения между одноуровневыми уровнями.

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

Вручную разметка Ваших иерархий слоев

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

При реализации пользовательского подкласса уровня подкласс может переопределить layoutSublayers метод и использование, что метод (вместо делегата) для обработки любых задач расположения. Необходимо только переопределить этот метод в случаях, где Вам нужен полный контроль над расположением подуровней в Вашем пользовательском классе уровня. Замена реализации по умолчанию препятствует тому, чтобы Базовая Анимация применила ограничения или автоизменила размеры правил о OS X.

Подуровни и отсечение

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

Форма маски отсечения уровня включает угловой радиус уровня, если Вы указаны. Рисунок 4-3 показывает уровень, демонстрирующий как masksToBounds свойство влияет на уровень со скругленными углами. Когда свойство установлено в NO, подуровни выведены на экран в их полноте, даже если они расширяются вне границ их родительского слоя. Изменение свойства к YES заставляет их содержание быть отсеченным.

  Подуровни Отсечения рисунка 4-3 к границам родителя

Преобразование координатных значений между уровнями

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

В дополнение к преобразованию точки и прямоугольных значений, можно также преобразовать временные стоимости между уровнями с помощью convertTime:fromLayer: и convertTime:toLayer: методы. Каждый уровень определяет свое собственное пространство местного времени и использует то пространство времени для синхронизации начала и окончания анимаций с остальной частью системы. Эти пробелы времени синхронизируются по умолчанию; однако, при изменении скорости анимации для одного набора уровней пространство времени для тех уровней изменяется соответственно. Можно использовать методы преобразования времени для составить любые такие факторы и гарантировать, что синхронизируется синхронизация обоих уровней.