Нарисуйте градиент под графиком CAShapeLayer

Я рисую график, используя CGPath, примененный к CAShapeLayer. Сам график нарисован отлично, но потом я хочу добавить под ним градиент. Моя проблема в том, что путь закрыт прямой линией, идущей от последней точки к первой (см. Ниже) - это сделало бы градиентную заливку совершенно нелепой.

введите описание изображения здесь

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

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

CGMutablePathRef graphPath = CGPathCreateMutable();

for (NSUInteger i = 0; i < self.coordinates.count; i++) {
    CGPoint coordinate = [self.coordinates[i] CGPointValue];

    if (!i) {
        CGPathMoveToPoint(graphPath, NULL, coordinate.x, coordinate.y);
    } else {
        CGPathAddLineToPoint(graphPath, NULL, coordinate.x, coordinate.y);
    }
}

CAShapeLayer *graphLayer = [CAShapeLayer new];
graphLayer.path = graphPath;
graphLayer.strokeColor = [UIColor whiteColor].CGColor;
graphLayer.fillColor = [UIColor redColor].CGColor;

[self.layer addSublayer:graphLayer];

Я надеюсь, что вы, ребята, можете мне помочь!

Обновление: вы предлагаете создать CAGradientLayer, а затем применить слой графика в качестве его маски. Однако я не понимаю, как это будет работать, когда график / путь выглядит так, как он. Я заменил изображение выше другим графиком, который, надеюсь, лучше иллюстрирует проблему (обратите внимание, что я дал CAShapeLayer красную заливку). На мой взгляд, если бы я применил вышеупомянутый слой в качестве маски CAGradientLayer, часть градиента лежала бы над графиком, а часть - ниже. Я хочу, чтобы весь градиент располагался прямо под графиком.


person wstr    schedule 10.09.2015    source источник
comment
Вот ваше решение: stackoverflow.com/a/7264787/312312   -  person Lefteris    schedule 10.09.2015
comment
Вы действительно хотите эту красную заливку? Или вы просто хотите, чтобы область под графиком была заполнена градиентом, а не видимой диагонали?   -  person rob mayoff    schedule 11.09.2015
comment
@robmayoff Мне не нужна красная заливка, нет; просто градиент, который начинается прямо под линией графика.   -  person wstr    schedule 11.09.2015
comment
@Lefteris Пожалуйста, посмотрите мое обновление. Я не думаю, что решение, на которое вы ссылаетесь, применимо к этой конкретной проблеме.   -  person wstr    schedule 12.09.2015


Ответы (2)


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

Выясните, какими бы ни были минимальные максимальные границы ваших координат, создайте CAGradientLayer этого размера, настройте его, как вам нравится, а затем примените свой graphLayer в качестве маски. Затем добавьте новый CAGradientLayer в свой слой self.layer.

CAGradientLayer *gradientLayer = [CAGradientLayer layer];
// ... Configure the gradientLayer colors / locations / size / etc...
gradientLayer.mask = graphLayer;

[self.layer addSubLayer:gradientLayer];

Это не учитывает обводку, но это не должно быть трудным, если это важно.

person Bain Kennedy    schedule 10.09.2015
comment
Я обновил свой пост, добавив новое изображение и дополнительную информацию. - person wstr; 11.09.2015

Я решил проблему, создав два отдельных пути: один для графика (как показано в моем исходном сообщении), а другой, который начинается в правом нижнем углу, движется по прямой линии в левый нижний угол, а оттуда следует тот же путь, что и граф. Таким образом, путь красиво замыкается, поскольку график заканчивается в той же координате x, что и путь, с которого начинался.

Оттуда я применил второй путь к CAShapeLayer, а затем использовал этот слой как маску слоя градиента.

person wstr    schedule 25.10.2015