Маска рисования влияет на производительность

Вот код, который я использую для рисования маски для UIView. Проблема в том, что если у меня есть более 5 UIViews с маской на экране, это влияет на производительность при перетаскивании UIViews: Как я могу улучшить код ниже?:

+ (UIBezierPath *)roundedPathAtCenter:(CGPoint)center size:(CGSize)size corner:(CGFloat)corner
{
    NSInteger width = size.width;
    NSInteger height = size.height;

    UIBezierPath *path = [UIBezierPath bezierPath];

    // upper left corner
    [path moveToPoint: CGPointMake(center.x - width / 2.0f + corner / 2.0f, center.y - height / 2.0f + corner / 2.0f)];

    // path to top center
    [path addQuadCurveToPoint: CGPointMake(center.x, center.y - height / 2.0f) controlPoint: CGPointMake(center.x - width / 2.0f + corner, center.y - height / 2.0f)];

    // path to upper right
    [path addQuadCurveToPoint: CGPointMake(center.x + width / 2.0f - corner / 2.0f, center.y - height / 2.0f + corner / 2.0f) controlPoint: CGPointMake(center.x + width / 2.0f - corner, center.y - height / 2.0f)];

    // path to mid right
    [path addQuadCurveToPoint: CGPointMake(center.x + width / 2.0f, center.y) controlPoint: CGPointMake(center.x + width / 2.0f, center.y - height / 2.0 + corner)];

    // path to lower right
    [path addQuadCurveToPoint: CGPointMake(center.x + width / 2.0 - corner / 2.0f, center.y + height / 2.0f - corner / 2.0f) controlPoint: CGPointMake(center.x + width / 2.0f, center.y + height / 2.0f - corner)];

    // path to center bottom
    [path addQuadCurveToPoint: CGPointMake(center.x, center.y + height / 2.0f) controlPoint: CGPointMake(center.x + width / 2.0 - corner, center.y + height / 2.0)];

    // path to lower left
    [path addQuadCurveToPoint: CGPointMake(center.x - width / 2.0f + corner / 2.0f, center.y + height / 2.0f - corner / 2.0f) controlPoint: CGPointMake(center.x - width / 2.0f + corner, center.y + height / 2.0f)];

    // path to mid left
    [path addQuadCurveToPoint: CGPointMake(center.x - width / 2.0f, center.y) controlPoint: CGPointMake(center.x - width / 2.0f, center.y + height / 2.0 - corner)];

    // path to top left

    [path addQuadCurveToPoint: CGPointMake(center.x - width / 2.0f + corner / 2.0f, center.y - height / 2.0f + corner / 2.0f) controlPoint: CGPointMake(center.x - width / 2.0f, center.y - height / 2.0f + corner)];

    [path closePath];

    return path;
}

Без добавления маски для UIViews работает очень быстро


person Serhii    schedule 21.03.2016    source источник


Ответы (2)


Есть два быстрых метода для повышения производительности в таких ситуациях:

  1. Прежде чем вы начнете перетаскивать UIView, вы можете установить shouldRasterize из layer из view в true, а когда вы закончите перетаскивать его, восстановите shouldRasterize в false. Иногда (особенно если перетаскиваемое изображение может меняться) это оказывает негативное влияние, но это просто попробовать, и вы увидите, улучшит ли это производительность.

  2. Другой подход заключается в ручном создании моментального снимка (например, рендеринг вида с его отсечением на UIImage) и замене вида на UIImageView, а затем перетаскивании его, а затем, когда вы отбрасываете его, заменяете исходным видом (если вы это нужно; иногда снимок — это все, что вам нужно).

Я мог бы предложить посмотреть видео WWDC 2012 Производительность приложений iOS: графика и анимация, которое иллюстрирует некоторые методы диагностики и решения проблем с производительностью графики. Видео может быть несколько лет, но методы все еще в значительной степени применимы. Видео Оптимизация производительности 2D-графики и анимации также может дать некоторую информацию (хотя я думаю, что другое видео, вероятно, будет более применимо здесь).

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

person Rob    schedule 21.03.2016

Анимация маскированных видов по своей природе медленная, потому что дерево рендеринга должно пересчитываться в каждом кадре. Как вы правильно заметили, не требуется много таких просмотров, которые одновременно анимируются, чтобы это стало очевидным (обычно при заикании). WWDC от Apple посвятил этому много отличных видеороликов, как правило, в контексте прокрутки (например, в виде таблицы); Я предлагаю посмотреть некоторые из этих видео, которые также предлагают обходные пути.

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

person matt    schedule 21.03.2016
comment
Кстати, вы обнаружите, что использование шаблона Core Animation для инструментов очень полезно для количественной оценки и точного определения причины здесь. - person matt; 21.03.2016