Основная структура кода анимации / соглашения

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

  • Мой подкласс NSView объявляет следующее в своем init. Это представление является частичным представлением обычного представления с поддержкой слоя.

    [self setLayer:[CALayer layer]];
    [self setWantsLayer:NO];
    

    После этого, когда и в каких ситуациях мне следует обращаться к себе, а не к [слою себя]? Я управлял слоем ТОЛЬКО с явной и неявной анимацией, избегая [self setFrame:] и т. Д. И используя [[self layer] setPosition] и т. Д.

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

  • Что касается уровня представления, очевидно, он доступен только во время реальной анимации. Есть ли какое-то свойство слоя, которое может сказать мне, где он ДЕЙСТВИТЕЛЬНО визуально, даже когда анимация не выполняется?


person cemulate    schedule 16.05.2009    source источник


Ответы (2)


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

  • PresentationLayer предоставляет информацию о текущем состоянии слоя во время «полета».

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

  • У NSView должна быть включена поддержка слоя, чтобы иметь возможность выполнять анимацию.

  • Убедитесь, что вы не просто анимируете явную анимацию и не устанавливаете значение слоя, который вы анимируете. Анимации не изменяют автоматически свойства анимируемых слоев. Вы должны сами изменить свойство на конечное значение, иначе оно просто «вернется» к начальному значению.

  • Если вы хотите анимировать вид, а не слой, вы можете использовать прокси-сервер аниматора, например [[view animator] setFrame:newFrame];

  • Оберните вызовы аниматора в CATrasaction, чтобы изменить такие вещи, как продолжительность анимации.

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

person Matt Long    schedule 19.08.2010

Во-первых, вы хотите использовать [self setWantsLayer: YES]. Кроме того, важно вызывать -setLayer: перед -setWantsLayer: только в том случае, если вы хотите предоставить конкретный подкласс CALayer (например, CAScrollLayer); если вам просто нужен обычный CALayer, просто вызовите -setWantsLayer:, и он будет создан для вас. Еще лучше, просто отметьте опцию «хочет слой» в Интерфейсном Разработчике.

Во-вторых, весь смысл использования представления с поддержкой слоев состоит в том, что вы можете продолжать использовать обычные методы NSView и получать бесплатные эффекты «анимации» CoreAnimation. Если вы хотите использовать CoreAnimation в качестве единственного средства перемещения элементов, то правильный способ сделать это - создать представление с поддержкой слоя, которое содержит вашу иерархию представления чистого CALayer.

Я не просматривал никаких бесплатных руководств по CoreAnimation, но я определенно могу порекомендовать книга по этой теме. У них также есть скринкаст доступно автором книги.

person Jim Dovey    schedule 17.05.2009