8

Прежде всего, я обнаружил, что онлайн-документы iPhone не очень-то очень понятны, когда речь заходит о различных способах рендеринга слоя. Я получаю его, но я не понимаю, когда использовать какие методы и который требует добавления слоя в качестве подслоя или нет.Жесткие проблемы с CALayer

Мой проект начался тривиально со мной, загружая изображения и просто рисуя их в UIView через [image drawAtPoint:], а также [image drawInRect:]. Они отлично работают с использованием текущего графического контекста.

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

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

  • drawLayer
  • DisplayLayer
  • дисплей
  • drawInContext

Теперь для всех этих методов, это требуется, чтобы установить размер кадра слоя? Требуется ли добавить слой к слою представления?

Единственный метод, который дает мне видимые результаты, - метод drawinContext. Но если я применяю неявную анимацию (например, image.opacity = 0), ничего не происходит, что заставляет меня полагать, что мой слой настроен неправильно.

Некоторые из них, пожалуйста, верните порядок в этот хаос.

ответ

18

Core Animation действительно делает такую ​​вещь тривиальной. Предложение Брэда верно. Суть в том, что вам не нужны какие-либо из этих методов, просто визуализировать слой. Для того, чтобы вызвать слой для визуализации, убедитесь, что вы сделали следующее:

  • Установите свойство содержимого с:

    [imageLayer setContents:(id)[[UIImage [email protected]"image.png"] CGImage]];

  • Установить границы слоя до размера вы хотите.

    [imageLayer setBounds:CGRectMake(0.0f, 0.0f, 50.0f, 50.0f)];

  • Установите положение (х, у) местоположения слоя для отображения в представлении. По умолчанию anchorPoint является центром слоя. Этот код центрирует слой в вашем представлении.

    [imageLayer setPosition:CGPointMake([view bounds].size.width/2, [view bounds].size.height/2)];

  • Добавьте слой к слою ваш взгляд в:

    [[[self view] layer] addSublayer:imageLayer];

Кстати, если вы хотите, вы можете установить обе границы и положение в одном методе, вызвав -setFrame :. Я предпочитаю использовать два вызова сам, поскольку он кажется мне более читаемым, но это зависит от ваших собственных предпочтений. Если вы не зададите границы и положение или кадр слоя, слой не будет отображаться.

Если вы предпочитаете, вы можете избежать использования drawInContext, создав дополнительные слои, которые рисуют пути, фигуры (см. CAShaperLayer) или дополнительные изображения и добавят их в качестве подслоев вашего уровня изображения или добавят их в качестве подслоев вашего родительского слоя и дать им zPosition, что заставляет их отображаться перед вашим слоем изображения.

Теперь, если вы хотите анимировать непрозрачность, вы можете использовать неявную анимацию, просто установив свойство слоя точно так, как вы описали, например. [imageLayer setOpacity: 0.0f]; Это уменьшит слой и все его дочерние слои более 0,25 секунды.

Просто несколько дополнительных мыслей.

С наилучшими пожеланиями.

2

Если все, что вы хотите, чтобы ваши различные слои отображались, отображают по одному изображению каждый, вам не нужно подклассифицировать их вообще. Вы должны просто установить изображение (в форме CGImageRef) на свойство contents каждого слоя. Затем слой обработает рисунок этого изображения. Вы можете получить представление изображения Core Graphics для UIImage, используя свойство CGImage для чтения.

Вы верны, однако, о -drawInContext:, являющемся подходящим местом для размещения дополнительного пользовательского кода чертежа в подклассе CALayer. Без подкласса CALayer у вас может быть делегат изменить поведение чертежа слоя с помощью метода делегата -drawLayer:inContext:.

Все это подробно описано в разделе "Providing Layer Content" раздела Apple Core Animation Programming Guide.

+0

То, что я закончил делать, является подклассом (потому что мои объекты сложны), и я сам делегировал делегат. Таким образом, в основном я использую displayLayer. Все, что мне нужно сделать, это вызвать setNeedsDisplay слоя. Итак, теперь остается вопрос об использовании drawInContext и drawLayer: inContext. Вызывается ли это вручную или вызывается внутренне через SetNeedsDisplay? Теперь просто любопытно. – AlvinfromDiaspar

+0

Вот еще более важный вопрос: Теперь я могу сделать слой с использованием слоя drawLayer: (CALayer *). Однако, если я хочу обновить рендеринг, скажем, анимационный кадр на слое, если я установил содержимое слоя с обновленным изображением *, содержимое исчезнет на экране. Нужно ли удалить слой, а затем визуализировать его, а затем снова добавить в дерево рендеринга? Если это так, это ударит! – AlvinfromDiaspar

+0

К вашему первому вопросу: drawInContext: никогда не следует вызывать напрямую, но косвенно запускается setNeedsDisplay. Если вы не переопределили этот метод, я верю, что он вызывает делегата, чтобы помочь отобразить содержимое через -drawLayer: inContext: –