2012-03-21 3 views
7

Я подклассифицирую CALayer для предоставления моего собственного метода рисования. Для оптимизации я звоню -[MyLayer setNeedsDisplayInRect:] вместо -[MyLayer setNeedsDisplay]. В методе рисования я получаю прямоугольник, который должен быть перерисован через CGContextGetClipBoundingBox().- [CALayer setNeedsDisplayInRect:] вызывает перерисовку всего слоя.

Если я использую этот слой как основу уровня UIView, каждая вещь работает так, как ожидалось. Проблема возникает, как только я использую свой пользовательский слой в качестве подуровня другого CALayer. Чем CGContextGetClipBoundingBox() всегда возвращает прямоугольник границ этого слоя.

Любые идеи?

[EDIT]

Кажется, что нет никакой гарантии, что содержание CALayer кэшируется и только грязная часть получает перерисованы. Я сделал небольшой тест и сохранил прямоугольник, который нужно отображать как отдельное свойство. Результат состоял в том, что только эта часть была видна на экране.

Теперь я представляю контекст изображения и сохраняю это изображение как кеш. В методе рисования я покажу только кешированное изображение.

+0

Имеются ли у слоев без просмотра свойство 'masksToBounds' для' YES'? Если нет, есть веская причина, почему они не будут зажимать. – MrMage

+0

К сожалению, это не решает проблему. Проблема заключается в том, что 'CGContextGetClipBoundingBox()' возвращает границы слоя, а не область, которую необходимо обновить, как описано в Apple: * Подклассы, которые хотят найти реальную область для рисования, могут вызывать CGContextGetClipBoundingBox. * [DrawInCOntext:] (https://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CALayer_class/Introduction/Introduction.html#//apple_ref/occ/instm/CALayer/drawInContext :) –

+0

Вы когда-нибудь добирались до в нижней части этого? У меня такая же неприятная проблема. – mprivat

ответ

6

Документация Apple, к сожалению, противоречива, поскольку документы -setNeedsDisplayInRect не указывают, работает ли метод на практике. Основываясь на собственном опыте, this technote устанавливает его прямо:

Обратите внимание, что, из-за способа, что iPhone/IPod Touch/IPad обновляет свой экран, весь вид будет перерисовывать, если вы звоните -setNeedsDisplayInRect: или -setNeedsDisplay :.

Это, как говорится, есть много вещей, на которые вы можете обратить внимание, если считаете, что вы ударяете о стену из-за избыточного рисунка.

  • Если вы рисуете изображения, самое большое улучшение производительности, которое вы можете сделать, это использовать изображения тех же размеров, на которых вы рисуете. Если это не так, попробуйте кэшировать свой образ, переведя его в какой-то контекст растрового изображения вне экрана и верните его позже.
  • Проверьте недвижимость shouldRasterize на CALayer. Это может быть находкой, если вы пытаетесь манипулировать слоем, подслои которого потенциально могут представлять собой сложную иерархию уровней. Не забудьте проверить, как вы делаете в Инструментах, пометив поле Color Hits Green and Misses Red в инструменте Core Animation. Если вы видите много красных, шансы на использование shouldRasterize ушибают больше, чем помогают.
  • Даже лучше, чем shouldRasterize, чтобы сгладить иерархию слоев, так как тогда вы можете избежать дополнительных накладных расходов, которые возникают при сглаживании иерархии уровней в реальном времени. Конечно, это не всегда возможно, но не бойтесь попробовать :)
  • Если вы рисуете изображения, попробуйте поэкспериментировать с вашим blending mode. Если вам приходится рисовать непрозрачные изображения, нет необходимости использовать обычные методы источника (которые используют как пропускную способность чтения, так и записи). Попробуйте kCGBlendModeCopy, который позволяет вам сократить расходы на чтение полосы пропускания.
  • Ознакомьтесь с CGLayerRef, который позволяет кэшировать вывод Core Graphics через различные вызовы вашим методам рисования. Мой опыт заключается в том, что, если вы не делаете хардкор-нажатие на пиксель, это становится более дорогостоящим, чем просто перерисовка. См. this для интересного чтения.
  • Прежде всего, Инструменты - ваш друг.Посмотрите пару видео из прошлых WWDC (2012, 2011, and 2010); все они имеют отличную информацию о том, как точно настроить производительность.

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

+0

Есть ли способ заставить нижние CALayers отложить их перерисовку/растеризацию до тех пор, пока другие UIViews не скроют их, а не упрется? – Confused

Смежные вопросы