Эффективно нарисовать CGPath на CATiledLayer - PullRequest
8 голосов
/ 03 февраля 2012

Как бы я эффективно нарисовал CGPath на CATiledLayer?В настоящее время я проверяю, пересекает ли ограничивающая рамка плитки ограничивающую рамку пути следующим образом:

-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context {
    CGRect boundingBox = CGPathGetPathBoundingBox(drawPath);
    CGRect rect = CGContextGetClipBoundingBox(context);

    if( !CGRectIntersectsRect(boundingBox, rect) )
        return;

    // Draw path...
}

Это не очень эффективно, поскольку drawLayer:inContext: вызывается несколько раз из нескольких потоков и результатов.при многократном рисовании пути.

Есть ли лучший, более эффективный способ сделать это?

Ответы [ 2 ]

5 голосов
/ 15 февраля 2012

Самый простой вариант - нарисовать кривую в большом изображении, а затем поместить его в мозаику. Но если вы укладываете плитку, это, вероятно, означает, что изображение будет слишком большим, или вы просто нарисовали путь в первую очередь, верно?

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

Технически вы будете «рисовать» вещи, которые выходят за ваши границы (например, линия, которая выходит за пределы плитки), но это намного дешевле, чем кажется. Core Graphics собирается очень просто обрезать отдельные элементы. Цель состоит в том, чтобы избежать вычисления элементов, которые вообще не находятся в вашей ограничительной рамке.

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

2 голосов
/ 14 февраля 2012

Вы не показываете, где создается путь. Если возможно, вы можете попытаться построить путь в методе -drawLayer:inContext:, создавая только ту его часть, которая нужна для рисования плитки.

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

Как примечание, есть ли причина, по которой вы используете CGPath вместо UIBezierPath? Из документации Apple :

Для создания путей в iOS рекомендуется использовать UIBezierPath вместо функций CGPath, если вам не нужны некоторые возможности это обеспечивает только Core Graphics, например, добавление эллипсов к путям. Подробнее о создании и рендеринге путей в UIKit см. «Рисование фигур». Использование путей Безье. ”

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