Как залить путь градиентом в drawRect :?

заполнить путь сплошным цветом достаточно просто:

CGPoint aPoint;
for (id pointValue in points)
{
    aPoint = [pointValue CGPointValue];
    CGContextAddLineToPoint(context, aPoint.x, aPoint.y);
}
[[UIColor redColor] setFill];
[[UIColor blackColor] setStroke];
CGContextDrawPath(context, kCGPathFillStroke);

Я хотел бы нарисовать градиент вместо сплошного красного цвета, но у меня возникли проблемы. Я пробовал код, указанный в вопросе / ответе: Градиенты в UIView и UILabels На iPhone

который:

CAGradientLayer *gradient = [CAGradientLayer layer];
[gradient setFrame:rect];
[gradient setColors:[NSArray arrayWithObjects:(id)[[UIColor blueColor] CGColor],
                (id)[[UIColor whiteColor] CGColor], nil]];
[[self layer] setMasksToBounds:YES];

[[self layer] insertSublayer:gradient atIndex:0];

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


person Derrick    schedule 06.06.2010    source источник


Ответы (1)


Я бы обрезал путь, который вы хотите заполнить, и использовал бы CGContextDrawLinearGradient. Вот простая реализация drawRect: в качестве примера:

- (void) drawRect:(CGRect)rect
{
    // Create a gradient from white to red
    CGFloat colors [] = { 
        1.0, 1.0, 1.0, 1.0, 
        1.0, 0.0, 0.0, 1.0
    };

    CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
    CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, NULL, 2);
    CGColorSpaceRelease(baseSpace), baseSpace = NULL;

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSaveGState(context);
    CGContextAddEllipseInRect(context, rect);
    CGContextClip(context);

    CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
    CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));

    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
    CGGradientRelease(gradient), gradient = NULL;

    CGContextRestoreGState(context);

    CGContextAddEllipseInRect(context, rect);
    CGContextDrawPath(context, kCGPathStroke);
}
person sbooth    schedule 06.06.2010
comment
Если бы я мог дать тебе отличный значок, я бы сделал это! Вы знаете какие-либо руководства по CGContextSaveGState и тому подобное? Потому что ссылка на класс Apple довольно тонкая. - person Derrick; 07.06.2010
comment
Derrick: Руководство по программированию Quartz 2D охватывает это, а также все остальное: developer.apple.com/mac/library/documentation/GraphicsImaging/ - person Peter Hosey; 07.06.2010
comment
После использования вашего примера кода моя тень исчезла. Я пробовал переместить теневую линию (CGContextSetShadow (context, CGSizeMake (5.0, -5.0), 4);) до сохранения gstate, после него, после восстановления gstate, после него, до и после обрезки - ничего не помогло. - person Doron; 03.07.2010
comment
@Doron После заливки или обводки (я думаю, даже обрезки) пути этот путь по существу равен нулю, и последующие заливки или обводки ничего не делают. Сначала вам нужно скопировать путь. - person daveMac; 18.10.2012
comment
@Doron - Расширяя то, что сказал daveMac, я обнаружил, что мне нужно вызывать CGContextAddPath (с моим скопированным ранее путем) между моими вызовами FillPath и Clip. - person ArtOfWarfare; 01.01.2013
comment
Я только что узнал о CGPathCreateCopyByStrokingPath, доступном в iOS 5 и более поздних версиях, который создает CGPath вокруг существующего пути. Это должно упростить рисование градиента, который вам нужен. - person Victor Engel; 29.04.2013