1

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];
El Tomato
  • 6,479
  • 6
  • 46
  • 75

4 Answers4

0

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);
Khanh Nguyen
  • 11,112
  • 10
  • 52
  • 65
0

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];
Sinisa Drpa
  • 887
  • 1
  • 5
  • 16
  • This question is about creating a float array. – El Tomato Jan 19 '14 at 12:26
  • CGFloat locations[3] = {0.0, 0.5, 1.0}; CGFloat is just a typedef for either float or double. You can see for yourself by Command-double-clicking on "CGFloat" in Xcode — it will jump to the CGBase.h header where the typedef is defined. – Sinisa Drpa Jan 20 '14 at 22:31
  • Two solutions have already been posted. Where are you going with your argument? – El Tomato Jan 20 '14 at 22:34
0

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.

Community
  • 1
  • 1
ChrisJF
  • 6,822
  • 4
  • 36
  • 41
  • `[NSGradient initWithColors]` _requires_ you to pass it a C-style array. That is the use case in the question. – peterflynn Mar 24 '16 at 03:16
-1

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];
El Tomato
  • 6,479
  • 6
  • 46
  • 75