Создание массива CGFloat для градиентных местоположений

Я пытаюсь создать градиентный цвет из массива словаря (colorArray2). Этот словарь содержит 5 ключей: r, g, b, a, p. r, g, b, a — значения компонентов (строки), p — местоположение. Я пытаюсь создать градиентный цвет с помощью initWithColors:atLocations:colorSpace. На данный момент у меня есть следующее.

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]]];
}

Итак, у меня есть массив (cArray), содержащий цвета. Чего я не знаю, так это как создать массив местоположений. Согласно документации, местоположения представляют собой массив значений CGFloat, содержащих местоположение каждого цвета в градиенте. Как перечислить все, что нужно для создания массива с плавающей запятой?

Спасибо за помощь.

Обновить

В частности, как мне заставить pArray получить что-то вроде

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

так что я могу иметь

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

person El Tomato    schedule 26.10.2013    source источник


Ответы (4)


документация NSGradient указывает, что параметр locations должен иметь тип const CGFloat*, поэтому вы не можете использовать NSArray*. Следующее должно работать:

// 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);
person Khanh Nguyen    schedule 26.10.2013
comment
Эм... Да. Думаю, у меня тоже так. Я отмечу ваш ответ. Спасибо. - person El Tomato; 26.10.2013

Я понял.

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];
person El Tomato    schedule 26.10.2013

Ты можешь использовать:

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];
person Sinisa Drpa    schedule 19.01.2014
comment
Этот вопрос касается создания массива с плавающей запятой. - person El Tomato; 19.01.2014
comment
Местоположение CGFloat[3] = {0,0, 0,5, 1,0}; CGFloat — это просто typedef для float или double. Вы можете убедиться сами, дважды щелкнув Command на CGFloat в Xcode — он перейдет к заголовку CGBase.h, где определено определение типа. - person Sinisa Drpa; 21.01.2014
comment
Два решения уже опубликованы. Куда ты идешь со своим аргументом? - person El Tomato; 21.01.2014

К другим ответам: нет. Просто нет.

Фактический ответ: Как мне сделать массив CGFloats в цели c?

Прежде всего, это Objective-C, а не C. Технически вы можете использовать malloc, но это действительно ужасный хак. Вы должны преобразовать в NSNumber, а затем вы можете заполнить NSArray. После этого вы можете конвертировать обратно, используя метод floatValue NSNumber. Этот способ является правильным Objective-C. Смешивание и сопоставление C и Obj-C просто создает спагетти-код, который трудно читать и в конечном итоге становится неподдерживаемым.

person ChrisJF    schedule 20.11.2014
comment
[NSGradient initWithColors] требует передачи массива в стиле C. Это вариант использования в вопросе. - person peterflynn; 24.03.2016