我需要在路径中显示一组CGColors。我尝试用CGGradient做这个,但我不希望颜色是值之间的混合。看起来最好的解决方案是使用GGShading对象,但我无法弄清楚它们是如何工作的。我主要想知道我需要为CGShading的CGFunction输入提供什么。
有人能指出我正确的方向,我需要使这个CGFunction看起来只是在指定的CGPath上显示一个数组去CGColors吗?
谢谢!
答案 0 :(得分:5)
也许有点晚了,所以我希望这对你有用。我已经列出了一个简单的UIView子类的代码,它使用你描述的着色绘制一个圆圈。带注释的代码应该是不言自明的。
@implementation CGShadingCircle
// This is the callback of our shading function.
// info: a pointer to our NSMutableArray of UIColor objects
// inData: contains a single float that gives is the current position within the gradient
// outData: we fill this with the color to display at the given position
static void CGShadingCallback(void* info, const float* inData, float* outData) {
// Our colors
NSMutableArray* colors = (NSMutableArray*)info;
// Position within the gradient, ranging from 0.0 to 1.0
CGFloat position = *inData;
// Find the color that we want to used based on the current position;
NSUInteger colorIndex = position * [colors count];
// Account for the edge case where position == 1.0
if (colorIndex >= [colors count])
colorIndex = [colors count] - 1;
// Get our desired color from the array
UIColor* color = [colors objectAtIndex:colorIndex];
// Copy the 4 color components (red, green, blue, alpha) to outData
memcpy(outData, CGColorGetComponents(color.CGColor), 4 * sizeof(CGFloat));
}
// Set up our colors and shading function
- (void)initInternal {
_colors = [[NSMutableArray alloc] init];
// Creating the colors in this way ensures that the underlying color space is UIDeviceRGBColorSpace
// and thus has 4 color components: red, green, blue, alpha
[_colors addObject:[UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:1.0f]]; // Red
[_colors addObject:[UIColor colorWithRed:0.0f green:1.0f blue:0.0f alpha:1.0f]]; // Green
[_colors addObject:[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:1.0f]]; // Blue
[_colors addObject:[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:1.0f]]; // White
[_colors addObject:[UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f]]; // Black
// Define the shading callbacks
CGFunctionCallbacks callbacks;
callbacks.version = 0; // Defaults to 0
callbacks.evaluate = CGShadingCallback; // This is our color selection function
callbacks.releaseInfo = NULL; // Not used
// As input to our function we want 1 value in the range [0.0, 1.0].
// This is our position within the 'gradient'.
size_t domainDimension = 1;
CGFloat domain[2] = {0.0f, 1.0f};
// The output of our function is 4 values, each in the range [0.0, 1.0].
// This is our selected color for the input position.
// The 4 values are the red, green, blue and alpha components.
size_t rangeDimension = 4;
CGFloat range[8] = {0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f};
// Create the shading function
_shadingFunction = CGFunctionCreate(_colors, domainDimension, domain, rangeDimension, range, &callbacks);
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self initInternal];
}
return self;
}
- (id)initWithCoder:(NSCoder*)decoder {
self = [super initWithCoder:decoder];
if (self) {
[self initInternal];
}
return self;
}
- (void)dealloc {
[_colors release];
CGFunctionRelease(_shadingFunction);
[super dealloc];
}
- (void)drawRect:(CGRect)rect {
CGRect b = self.bounds;
CGContextRef ctx = UIGraphicsGetCurrentContext();
// Create a simple elliptic path
CGContextAddEllipseInRect(ctx, b);
// Set the current path as the clipping path
CGContextClip(ctx);
// Create our shading using the function that was defined earlier.
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGShadingRef shading = CGShadingCreateAxial(colorspace,
CGPointMake(CGRectGetMinX(b), CGRectGetMidY(b)),
CGPointMake(CGRectGetMaxX(b), CGRectGetMidY(b)),
_shadingFunction,
true,
true);
// Draw the shading
CGContextDrawShading(ctx, shading);
// Cleanup
CGShadingRelease(shading);
CGColorSpaceRelease(colorspace);
}
@end
这给了我以下输出:
我希望这有帮助!