您可以使用NSArray 和NSNumber 文字语法来获得类似的东西。你可以这样称呼它:
[self setGradientColorComponents:@[
@0.0f, @0.8f, @0.0f, @1.0f, // green
@1.0f, @1.0f, @0.0f, @1.0f, // yellow
@0.9f, @0.0f, @0.0f, @1.0f // red
] withLocations:@[
@0.0f, @0.5f, @1.0f
]];
这是你如何实现它的:
- (void)setGradientColorComponents:(NSArray *)components withLocations:(NSArray *)locations {
NSUInteger count = components.count;
CGFloat componentFloats[count];
for (NSUInteger i = 0; i < count; ++i) {
componentFloats[i] = [components[i] floatValue];
}
count = locations.count;
CGFloat locationFloats[count];
for (NSUInteger i = 0; i < count; ++i) {
locationFloats[i] = [locations[i] floatValue];
}
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(rgb, componentFloats, locationFloats, count);
CGColorSpaceRelease(rgb);
// do whatever with gradient
CGGradientRelease(gradient);
}
另一方面,您可以使用可变参数函数。由于可变参数函数只能有一个可变参数列表,因此您必须将位置与颜色分量混合。您还必须以某种方式标记列表的末尾。你可以这样称呼它:
[self setGradient:
0.0, 0.0, 0.8, 0.0, 1.0, // location 0.0, color green
0.5, 1.0, 1.0, 0.0, 1.0, // location 0.5, color yellow
1.0, 0.9, 0.0, 0.0, 1.0, // location 1.0, color red
-1.0
];
这更危险,因为您需要确保只将双精度值传递给函数,并且需要确保您通过列表末尾的 -1.0 标记。我建议坚持我的第一个解决方案(使用 NSArray 和 NSNumber 文字)。也就是说,这是实现可变参数解决方案的方式:
- (void)setGradient:(CGFloat)location0, ... {
size_t count = 0;
va_list ap;
va_start(ap, location0);
// Note that when you pass a float as a variadic argument, the compiler promotes it to double.
double f = location0;
while (f >= 0.0 && f <= 1.0) {
++count;
f = va_arg(ap, double);
}
va_end(ap);
NSAssert(count % 5 == 0, @"number of arguments is %lu which is not a multiple of 5", (unsigned long)count);
count /= 5;
CGFloat locations[count];
CGFloat components[4 * count];
va_start(ap, location0);
f = location0;
for (size_t i = 0; i < count; ++i) {
locations[i] = (CGFloat)f; f = va_arg(ap, double);
components[i * 4 + 0] = (CGFloat)f; f = va_arg(ap, double);
components[i * 4 + 1] = (CGFloat)f; f = va_arg(ap, double);
components[i * 4 + 2] = (CGFloat)f; f = va_arg(ap, double);
components[i * 4 + 3] = (CGFloat)f; f = va_arg(ap, double);
}
va_end(ap);
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(rgb, components, locations, count);
CGColorSpaceRelease(rgb);
// do whatever with gradient
CGGradientRelease(gradient);
}