Question

I'm trying to create a gradient color out of an array of dictionary (colorArray2). This dictionary contains 5 keys: r, g, b, a, p. r, g, b, a are component values (strings), p being the location. I'm trying to create a gradient color with initWithColors:atLocations:colorSpace. For now, I have the following.

NSGradient *aGradient;
NSColorSpace *space = [NSColorSpace genericRGBColorSpace];
NSMutableArray *cArray = [[NSMutableArray alloc] initWithObjects:nil]; // storing colors
NSMutableArray *pArray = [[NSMutableArray alloc] initWithObjects:nil]; // storing locations
for (NSInteger i2 = 0; i2 < colorArray2.count; i2++) {
    NSString *r = [[colorArray2 objectAtIndex:i2] objectForKey:key2a];
    NSString *g = [[colorArray2 objectAtIndex:i2] objectForKey:key2b];
    NSString *b = [[colorArray2 objectAtIndex:i2] objectForKey:key2c];
    NSString *a = [[colorArray2 objectAtIndex:i2] objectForKey:key2d];
    NSString *p = [[colorArray2 objectAtIndex:i2] objectForKey:key2e];
    NSColor *color = [NSColor colorWithSRGBRed:[r integerValue]/255.0f green:[g integerValue]/255.0f blue:[b integerValue]/255.0f alpha:[a integerValue]/100.0f];
    [cArray addObject:color];
    [pArray addObject:[NSNumber numberWithDouble:[p doubleValue]]];
}

So I have an array (cArray) containing colors. What I don't know is how to create an array of locations. According to the documentation, locations is an array of CGFloat values containing the location for each color in the gradient. How do I enumerate whatever to create a float array?

Thank you for your help.

Update

More specifically, how do I make pArray to get something like

double d[] = {0.1, 0.2, 0.3, 0.5, 1.0};

so that I can have

aGradient = [[NSGradient alloc] initWithColors:cArray atLocations:d colorSpace:space];
Was it helpful?

Solution

NSGradient's documentation states that locations parameter should be of type const CGFloat*, so you can't use NSArray*. The following should work:

// Allocate a C-array with the same length of colorArray2
CGFloat* pArray = (CGFloat*)malloc(colorArray2.count * sizeof(CGFloat));

for (NSInteger i2 = 0; i2 < colorArray2.count; i2++) {
    // Extract location
    NSString* p = [[colorArray2 objectAtIndex:i2] objectForKey:key2e];
    pArray[i2] = [p doubleValue];
}

// Do whaterver with pArray

...

// Remember to free it

free(pArray);

OTHER TIPS

I got it.

NSInteger count,index;
double *dArray;

count = pArray.count;
dArray = (double *) malloc(sizeof(double) * count);
for (index = 0; index < count; index++) {
    dArray[index] = [[pArray objectAtIndex:index] floatValue];
}

aGradient = [[NSGradient alloc] initWithColors:cArray atLocations:dArray colorSpace:space];

You can use:

NSArray *colors = @[[NSColor colorWithWhite:.3 alpha:1.0],
                   [NSColor colorWithWhite:.6 alpha:1.0],
                   [NSColor colorWithWhite:.3 alpha:1.0]];
CGFloat locations[3] = {0.0, 0.5, 1.0};
NSGradient *gradient = [[NSGradient alloc] initWithColors:colors atLocations:locations colorSpace:[NSColorSpace genericRGBColorSpace]];
[gradient drawInRect:CGRectMake(100.0, 7.0, 10.0, 18.0) angle:-90];

To the other answers: no. Just no.

Actual answer: How do I make an array of CGFloats in objective c?

First of all, this is Objective-C, not C. Technically you can use malloc, but that's a really terrible hack. You should convert to an NSNumber and then you can populate the NSArray. After, you can convert back using NSNumber's floatValue method. This way is proper Objective-C. Mixing and matching C and Obj-C just creates spaghetti code which is hard to read and eventually becomes unmaintainable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top