objective c - Gráficos principales de iOS: dibuje SOLO las sombras de un CGPath
objective-c core-graphics (1)
Estoy dibujando un camino simple en iOS 5 con Core Graphics:
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint( path, NULL, center.x , topMargin );
CGPathAddLineToPoint(path, NULL, center.x+20, topMargin+50);
CGPathAddLineToPoint(path, NULL, center.x , topMargin+40);
CGPathAddLineToPoint(path, NULL, center.x-20, topMargin+50);
CGPathAddLineToPoint(path, NULL, center.x , topMargin );
Ahora quiero rellenarlo en modo de superposición así:
[[UIColor colorWithRed:0 green:0 blue:0 alpha:0.4] setFill];
CGContextAddPath(context, path);
CGContextSetBlendMode (context, kCGBlendModeOverlay);
CGContextFillPath(context);
Lo que me da exactamente el resultado esperado. Pero a continuación, quiero crear un efecto en relieve. Pensé en usar una sombra blanca y una negra para lograr este efecto así:
[[UIColor colorWithRed:0 green:0 blue:0 alpha:0] setFill];
CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(1, 1), 1.0, highlightColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);
[[UIColor colorWithRed:0 green:0 blue:0 alpha:0] setFill];
CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(-1, -1), 1.0, shadowColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);
El problema es que las sombras no se dibujan cuando alfa se establece en 0.
Ahora la pregunta: ¿hay una forma de dibujar solo las sombras sin el color de relleno pero en alfa completo? ¿Puedo evitar de alguna manera que se dibuje el interior de mi camino? ¿O tal vez hay una forma más simple de dibujar dos sombras para un camino?
Le sugiero que establezca la ruta de recorte del contexto al inverso de la ruta de la forma, configure la sombra y rellene la forma normalmente, con total opacidad. El trazado de recorte ocultará el color de relleno y solo quedará la sombra.
CGContextSaveGState(context);
CGRect boundingRect = CGContextGetClipBoundingBox(context);
CGContextAddRect(context, boundingRect);
CGContextAddPath(context, path);
CGContextEOClip(context);
[[UIColor blackColor] setFill];
CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(1, 1), 1.0, highlightColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);
CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(-1, -1), 1.0, shadowColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);
CGContextRestoreGState(context);
El truco consiste en utilizar CGContextEOClip
y una CGContextEOClip
rectángulo adicional para establecer el área de recorte en lo que no esté cubierto por la ruta original. Esto funcionará para cualquier camino que no sea de auto-intersección.